// for finding memory leaks in debug mode with Visual Studio#if defined _DEBUG && defined _MSC_VER#include <crtdbg.h>#endif #define _FILE_OFFSET_BITS 64 #include <stdint.h>#include <stdio.h>#include <math.h>#ifdef _WIN32#define WIN32_MEAN_AND_LEAN#include <shlwapi.h>#include <windows.h>#include <direct.h>#include <shlobj.h> // SHGetFolderPathW()#else#include <sys/types.h>#include <sys/stat.h>#include <fts.h> // for fts_open() and stuff in recursiveDelete()#include <unistd.h>#include <dirent.h>#endif#include <wchar.h>#include <sys/stat.h>#include "ft2_header.h"#include "ft2_unicode.h"#include "ft2_config.h"#include "ft2_mouse.h"#include "ft2_gui.h"#include "ft2_pattern_ed.h"#include "ft2_sample_loader.h"#include "ft2_sample_saver.h"#include "ft2_diskop.h"#include "ft2_wav_renderer.h"#include "ft2_module_loader.h"#include "ft2_module_saver.h"#include "ft2_events.h"#include "ft2_video.h"#include "ft2_inst_ed.h"#include "ft2_structs.h" // hide POSIX warnings for chdir()#ifdef _MSC_VER#pragma warning(disable: 4996)#endif #define FILENAME_TEXT_X 170#define FILESIZE_TEXT_X 295#define DISKOP_MAX_DRIVE_BUTTONS 8 #ifdef _WIN32#define PARENT_DIR_STR L".."static HANDLE hFind;#else#define PARENT_DIR_STR ".."static DIR *hFind;#endif // "look for file" flagsenum{ LFF_DONE = 0, LFF_SKIP = 1, LFF_OK = 2}; typedef struct DirRec{ UNICHAR *nameU; bool isDir; int32_t filesize;} DirRec; static char FReq_SysReqText[256], *FReq_FileName, *FReq_NameTemp;static char *modTmpFName, *insTmpFName, *smpTmpFName, *patTmpFName, *trkTmpFName;static char *modTmpFNameUTF8; // for window titlestatic uint8_t FReq_Item;static bool FReq_ShowAllFiles, insPathSet, smpPathSet, patPathSet, trkPathSet, firstTimeOpeningDiskOp = true;static int32_t FReq_EntrySelected = -1, FReq_FileCount, FReq_DirPos, lastMouseY;static UNICHAR *FReq_CurPathU, *FReq_ModCurPathU, *FReq_InsCurPathU, *FReq_SmpCurPathU, *FReq_PatCurPathU, *FReq_TrkCurPathU;static DirRec *FReq_Buffer;static SDL_Thread *thread; static void setDiskOpItem(uint8_t item); bool setupExecutablePath(void){ editor.binaryPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); if (editor.binaryPathU == NULL) { showErrorMsgBox("Not enough memory!"); return false; } editor.binaryPathU[0] = 0; UNICHAR_GETCWD(editor.binaryPathU, PATH_MAX); return true;} int32_t getFileSize(UNICHAR *fileNameU) // returning -1 = filesize over 2GB{ int64_t fSize; #ifdef _WIN32 FILE *f = UNICHAR_FOPEN(fileNameU, "rb"); if (f == NULL) return 0; _fseeki64(f, 0, SEEK_END); fSize = _ftelli64(f); fclose(f);#else struct stat st; if (stat(fileNameU, &st) != 0) return 0; fSize = (int64_t)st.st_size;#endif if (fSize < 0) fSize = 0; if (fSize > INT32_MAX) return -1; // -1 = ">2GB" flag return (int32_t)fSize;} uint8_t getDiskOpItem(void){ return FReq_Item;} char *getCurrSongFilename(void) // for window title{ return modTmpFNameUTF8;} void updateCurrSongFilename(void) // for window title{ if (modTmpFNameUTF8 != NULL) { free(modTmpFNameUTF8); modTmpFNameUTF8 = NULL; } if (modTmpFName == NULL) return; modTmpFNameUTF8 = cp437ToUtf8(modTmpFName);} // drive buttons for Windows#ifdef _WIN32static char logicalDriveNames[26][3] = { "A:", "B:", "C:", "D:", "E:", "F:", "G:", "H:", "I:", "J:", "K:", "L:", "M:", "N:", "O:", "P:", "Q:", "R:", "S:", "T:", "U:", "V:", "W:", "X:", "Y:", "Z:"};static uint32_t numLogicalDrives;static uint32_t driveIndexes[DISKOP_MAX_DRIVE_BUTTONS];#endif char *getDiskOpFilename(void){ return FReq_FileName;} const UNICHAR *getDiskOpCurPath(void){ return FReq_CurPathU;} const UNICHAR *getDiskOpModPath(void){ return FReq_ModCurPathU;} const UNICHAR *getDiskOpSmpPath(void){ return FReq_SmpCurPathU;} static void setupInitialPaths(void){ // the UNICHAR paths are already zeroed out #ifdef _WIN32 if (config.modulesPath[0] != '\0') { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.modulesPath, -1, FReq_ModCurPathU, 80); FReq_ModCurPathU[80] = 0; } if (config.instrPath[0] != '\0') { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.instrPath, -1, FReq_InsCurPathU, 80); FReq_InsCurPathU[80] = 0; insPathSet = true; } if (config.samplesPath[0] != '\0') { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.samplesPath, -1, FReq_SmpCurPathU, 80); FReq_SmpCurPathU[80] = 0; smpPathSet = true; } if (config.patternsPath[0] != '\0') { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.patternsPath, -1, FReq_PatCurPathU, 80); FReq_PatCurPathU[80] = 0; patPathSet = true; } if (config.tracksPath[0] != '\0') { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.tracksPath, -1, FReq_TrkCurPathU, 80); FReq_TrkCurPathU[80] = 0; trkPathSet = true; }#else if (config.modulesPath[0] != '\0') { strncpy(FReq_ModCurPathU, config.modulesPath, 80); FReq_ModCurPathU[80] = 0; } if (config.instrPath[0] != '\0') { strncpy(FReq_InsCurPathU, config.instrPath, 80); FReq_InsCurPathU[80] = 0; insPathSet = true; } if (config.samplesPath[0] != '\0') { strncpy(FReq_SmpCurPathU, config.samplesPath, 80); FReq_SmpCurPathU[80] = 0; smpPathSet = true; } if (config.patternsPath[0] != '\0') { strncpy(FReq_PatCurPathU, config.patternsPath, 80); FReq_PatCurPathU[80] = 0; patPathSet = true; } if (config.tracksPath[0] != '\0') { strncpy(FReq_TrkCurPathU, config.tracksPath, 80); FReq_TrkCurPathU[80] = 0; trkPathSet = true; }#endif} static void freeDirRecBuffer(void){ if (FReq_Buffer != NULL) { for (int32_t i = 0; i < FReq_FileCount; i++) { if (FReq_Buffer[i].nameU != NULL) free(FReq_Buffer[i].nameU); } free(FReq_Buffer); FReq_Buffer = NULL; } FReq_FileCount = 0;} void freeDiskOp(void){ if (editor.tmpFilenameU != NULL) { free(editor.tmpFilenameU); editor.tmpFilenameU = NULL; } if (editor.tmpInstrFilenameU != NULL) { free(editor.tmpInstrFilenameU); editor.tmpInstrFilenameU = NULL; } if (modTmpFName != NULL) { free(modTmpFName); modTmpFName = NULL; } if (insTmpFName != NULL) { free(insTmpFName); insTmpFName = NULL; } if (smpTmpFName != NULL) { free(smpTmpFName); smpTmpFName = NULL; } if (patTmpFName != NULL) { free(patTmpFName); patTmpFName = NULL; } if (trkTmpFName != NULL) { free(trkTmpFName); trkTmpFName = NULL; } if (FReq_NameTemp != NULL) { free(FReq_NameTemp); FReq_NameTemp = NULL; } if (FReq_ModCurPathU != NULL) { free(FReq_ModCurPathU); FReq_ModCurPathU = NULL; } if (FReq_InsCurPathU != NULL) { free(FReq_InsCurPathU); FReq_InsCurPathU = NULL; } if (FReq_SmpCurPathU != NULL) { free(FReq_SmpCurPathU); FReq_SmpCurPathU = NULL; } if (FReq_PatCurPathU != NULL) { free(FReq_PatCurPathU); FReq_PatCurPathU = NULL; } if (FReq_TrkCurPathU != NULL) { free(FReq_TrkCurPathU); FReq_TrkCurPathU = NULL; } if (modTmpFNameUTF8 != NULL) { free(modTmpFNameUTF8); modTmpFNameUTF8 = NULL; } freeDirRecBuffer();} bool setupDiskOp(void){ modTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); insTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); smpTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); patTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); trkTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); FReq_NameTemp = (char *)malloc((PATH_MAX + 1) * sizeof (char)); FReq_ModCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); FReq_InsCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); FReq_SmpCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); FReq_PatCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); FReq_TrkCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); if (modTmpFName == NULL || insTmpFName == NULL || smpTmpFName == NULL || patTmpFName == NULL || trkTmpFName == NULL || FReq_NameTemp == NULL || FReq_ModCurPathU == NULL || FReq_InsCurPathU == NULL || FReq_SmpCurPathU == NULL || FReq_PatCurPathU == NULL || FReq_TrkCurPathU == NULL) { // allocated memory is free'd lateron showErrorMsgBox("Not enough memory!"); return false; } // clear first entry of strings modTmpFName[0] = '\0'; insTmpFName[0] = '\0'; smpTmpFName[0] = '\0'; patTmpFName[0] = '\0'; trkTmpFName[0] = '\0'; FReq_NameTemp[0] = '\0'; FReq_ModCurPathU[0] = 0; FReq_InsCurPathU[0] = 0; FReq_SmpCurPathU[0] = 0; FReq_PatCurPathU[0] = 0; FReq_TrkCurPathU[0] = 0; strcpy(modTmpFName, "untitled.xm"); strcpy(insTmpFName, "untitled.xi"); strcpy(smpTmpFName, "untitled.wav"); strcpy(patTmpFName, "untitled.xp"); strcpy(trkTmpFName, "untitled.xt"); setupInitialPaths(); setDiskOpItem(0); updateCurrSongFilename(); // for window title updateWindowTitle(true); return true;} int32_t getExtOffset(char *s, int32_t stringLen) // get byte offset of file extension (last '.'){ if (s == NULL || stringLen < 1) return -1; for (int32_t i = stringLen - 1; i >= 0; i--) { if (i != 0 && s[i] == '.') return i; } return -1;} static void removeQuestionmarksFromString(char *s){ if (s == NULL || *s == '\0') return; const int32_t len = (int32_t)strlen(s); for (int32_t i = 0; i < len; i++) { if (s[i] == '?') s[i] = ' ' ; }} #ifdef _WIN32 // WINDOWS SPECIFIC FILE OPERATION ROUTINES bool fileExistsAnsi(char *str){ UNICHAR *strU = cp437ToUnichar(str); if (strU == NULL) return false; bool retVal = PathFileExistsW(strU); free(strU); return retVal;} static bool deleteDirRecursive(UNICHAR *strU){ SHFILEOPSTRUCTW shfo; memset(&shfo, 0, sizeof (shfo)); shfo.wFunc = FO_DELETE; shfo.fFlags = FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMATION; shfo.pFrom = strU; return (SHFileOperationW(&shfo) == 0);} static bool makeDirAnsi(char *str){ UNICHAR *strU = cp437ToUnichar(str); if (strU == NULL) return false; int32_t retVal = _wmkdir(strU); free(strU); return (retVal == 0);} static bool renameAnsi(UNICHAR *oldNameU, char *newName){ UNICHAR *newNameU = cp437ToUnichar(newName); if (newNameU == NULL) return false; int32_t retVal = UNICHAR_RENAME(oldNameU, newNameU); free(newNameU); return (retVal == 0);} static void setupDiskOpDrives(void) // Windows only{ fillRect(134, 29, 31, 111, PAL_DESKTOP); numLogicalDrives = 0; // get number of drives and drive names const uint32_t drivesBitmask = GetLogicalDrives(); for (int32_t i = 0; i < 8*sizeof (uint32_t); i++) { if ((drivesBitmask & (1 << i)) != 0) { driveIndexes[numLogicalDrives++] = i; if (numLogicalDrives == DISKOP_MAX_DRIVE_BUTTONS) break; } } // hide all buttons for (uint16_t i = 0; i < DISKOP_MAX_DRIVE_BUTTONS; i++) hidePushButton(PB_DISKOP_DRIVE1 + i); // set button names and show buttons for (uint16_t i = 0; i < numLogicalDrives; i++) { pushButtons[PB_DISKOP_DRIVE1 + i].caption = logicalDriveNames[driveIndexes[i]]; showPushButton(PB_DISKOP_DRIVE1 + i); }} static void openDrive(char *str) // Windows only{ if (mouse.mode == MOUSE_MODE_DELETE) { okBox(8, "System complaint", "Very funny."); return; } if (str == NULL || *str == '\0') { okBox(0, "System message", "Couldn't open drive!"); return; } if (chdir(str) != 0) okBox(0, "System message", "Couldn't open drive! Please make sure there's a disk in it."); else editor.diskOpReadDir = true;} #else // NON-WINDOWS SPECIFIC FILE OPERATION ROUTINES bool fileExistsAnsi(char *str){ UNICHAR *strU = cp437ToUnichar(str); if (strU == NULL) return false; int32_t retVal = access(strU, F_OK); free(strU); return (retVal != -1);} static bool deleteDirRecursive(UNICHAR *strU)Lines 1–500 of 2540. Load more
// for finding memory leaks in debug mode with Visual Studio #if defined _DEBUG && defined _MSC_VER #include <crtdbg.h> #endif #define _FILE_OFFSET_BITS 64 #include <stdint.h> #include <stdio.h> #include <math.h> #ifdef _WIN32 #define WIN32_MEAN_AND_LEAN #include <shlwapi.h> #include <windows.h> #include <direct.h> #include <shlobj.h> // SHGetFolderPathW() #else #include <sys/types.h> #include <sys/stat.h> #include <fts.h> // for fts_open() and stuff in recursiveDelete() #include <unistd.h> #include <dirent.h> #endif #include <wchar.h> #include <sys/stat.h> #include "ft2_header.h" #include "ft2_unicode.h" #include "ft2_config.h" #include "ft2_mouse.h" #include "ft2_gui.h" #include "ft2_pattern_ed.h" #include "ft2_sample_loader.h" #include "ft2_sample_saver.h" #include "ft2_diskop.h" #include "ft2_wav_renderer.h" #include "ft2_module_loader.h" #include "ft2_module_saver.h" #include "ft2_events.h" #include "ft2_video.h" #include "ft2_inst_ed.h" #include "ft2_structs.h" // hide POSIX warnings for chdir() #ifdef _MSC_VER #pragma warning(disable: 4996) #endif #define FILENAME_TEXT_X 170 #define FILESIZE_TEXT_X 295 #define DISKOP_MAX_DRIVE_BUTTONS 8 #ifdef _WIN32 #define PARENT_DIR_STR L".." static HANDLE hFind; #else #define PARENT_DIR_STR ".." static DIR *hFind; #endif // "look for file" flags enum { LFF_DONE = 0, LFF_SKIP = 1, LFF_OK = 2 }; typedef struct DirRec { UNICHAR *nameU; bool isDir; int32_t filesize; } DirRec; static char FReq_SysReqText[256], *FReq_FileName, *FReq_NameTemp; static char *modTmpFName, *insTmpFName, *smpTmpFName, *patTmpFName, *trkTmpFName; static char *modTmpFNameUTF8; // for window title static uint8_t FReq_Item; static bool FReq_ShowAllFiles, insPathSet, smpPathSet, patPathSet, trkPathSet, firstTimeOpeningDiskOp = true; static int32_t FReq_EntrySelected = -1, FReq_FileCount, FReq_DirPos, lastMouseY; static UNICHAR *FReq_CurPathU, *FReq_ModCurPathU, *FReq_InsCurPathU, *FReq_SmpCurPathU, *FReq_PatCurPathU, *FReq_TrkCurPathU; static DirRec *FReq_Buffer; static SDL_Thread *thread; static void setDiskOpItem(uint8_t item); bool setupExecutablePath(void) { editor.binaryPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); if (editor.binaryPathU == NULL) { showErrorMsgBox("Not enough memory!"); return false; } editor.binaryPathU[0] = 0; UNICHAR_GETCWD(editor.binaryPathU, PATH_MAX); return true; } int32_t getFileSize(UNICHAR *fileNameU) // returning -1 = filesize over 2GB { int64_t fSize; #ifdef _WIN32 FILE *f = UNICHAR_FOPEN(fileNameU, "rb"); if (f == NULL) return 0; _fseeki64(f, 0, SEEK_END); fSize = _ftelli64(f); fclose(f); #else struct stat st; if (stat(fileNameU, &st) != 0) return 0; fSize = (int64_t)st.st_size; #endif if (fSize < 0) fSize = 0; if (fSize > INT32_MAX) return -1; // -1 = ">2GB" flag return (int32_t)fSize; } uint8_t getDiskOpItem(void) { return FReq_Item; } char *getCurrSongFilename(void) // for window title { return modTmpFNameUTF8; } void updateCurrSongFilename(void) // for window title { if (modTmpFNameUTF8 != NULL) { free(modTmpFNameUTF8); modTmpFNameUTF8 = NULL; } if (modTmpFName == NULL) return; modTmpFNameUTF8 = cp437ToUtf8(modTmpFName); } // drive buttons for Windows #ifdef _WIN32 static char logicalDriveNames[26][3] = { "A:", "B:", "C:", "D:", "E:", "F:", "G:", "H:", "I:", "J:", "K:", "L:", "M:", "N:", "O:", "P:", "Q:", "R:", "S:", "T:", "U:", "V:", "W:", "X:", "Y:", "Z:" }; static uint32_t numLogicalDrives; static uint32_t driveIndexes[DISKOP_MAX_DRIVE_BUTTONS]; #endif char *getDiskOpFilename(void) { return FReq_FileName; } const UNICHAR *getDiskOpCurPath(void) { return FReq_CurPathU; } const UNICHAR *getDiskOpModPath(void) { return FReq_ModCurPathU; } const UNICHAR *getDiskOpSmpPath(void) { return FReq_SmpCurPathU; } static void setupInitialPaths(void) { // the UNICHAR paths are already zeroed out #ifdef _WIN32 if (config.modulesPath[0] != '\0') { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.modulesPath, -1, FReq_ModCurPathU, 80); FReq_ModCurPathU[80] = 0; } if (config.instrPath[0] != '\0') { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.instrPath, -1, FReq_InsCurPathU, 80); FReq_InsCurPathU[80] = 0; insPathSet = true; } if (config.samplesPath[0] != '\0') { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.samplesPath, -1, FReq_SmpCurPathU, 80); FReq_SmpCurPathU[80] = 0; smpPathSet = true; } if (config.patternsPath[0] != '\0') { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.patternsPath, -1, FReq_PatCurPathU, 80); FReq_PatCurPathU[80] = 0; patPathSet = true; } if (config.tracksPath[0] != '\0') { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.tracksPath, -1, FReq_TrkCurPathU, 80); FReq_TrkCurPathU[80] = 0; trkPathSet = true; } #else if (config.modulesPath[0] != '\0') { strncpy(FReq_ModCurPathU, config.modulesPath, 80); FReq_ModCurPathU[80] = 0; } if (config.instrPath[0] != '\0') { strncpy(FReq_InsCurPathU, config.instrPath, 80); FReq_InsCurPathU[80] = 0; insPathSet = true; } if (config.samplesPath[0] != '\0') { strncpy(FReq_SmpCurPathU, config.samplesPath, 80); FReq_SmpCurPathU[80] = 0; smpPathSet = true; } if (config.patternsPath[0] != '\0') { strncpy(FReq_PatCurPathU, config.patternsPath, 80); FReq_PatCurPathU[80] = 0; patPathSet = true; } if (config.tracksPath[0] != '\0') { strncpy(FReq_TrkCurPathU, config.tracksPath, 80); FReq_TrkCurPathU[80] = 0; trkPathSet = true; } #endif } static void freeDirRecBuffer(void) { if (FReq_Buffer != NULL) { for (int32_t i = 0; i < FReq_FileCount; i++) { if (FReq_Buffer[i].nameU != NULL) free(FReq_Buffer[i].nameU); } free(FReq_Buffer); FReq_Buffer = NULL; } FReq_FileCount = 0; } void freeDiskOp(void) { if (editor.tmpFilenameU != NULL) { free(editor.tmpFilenameU); editor.tmpFilenameU = NULL; } if (editor.tmpInstrFilenameU != NULL) { free(editor.tmpInstrFilenameU); editor.tmpInstrFilenameU = NULL; } if (modTmpFName != NULL) { free(modTmpFName); modTmpFName = NULL; } if (insTmpFName != NULL) { free(insTmpFName); insTmpFName = NULL; } if (smpTmpFName != NULL) { free(smpTmpFName); smpTmpFName = NULL; } if (patTmpFName != NULL) { free(patTmpFName); patTmpFName = NULL; } if (trkTmpFName != NULL) { free(trkTmpFName); trkTmpFName = NULL; } if (FReq_NameTemp != NULL) { free(FReq_NameTemp); FReq_NameTemp = NULL; } if (FReq_ModCurPathU != NULL) { free(FReq_ModCurPathU); FReq_ModCurPathU = NULL; } if (FReq_InsCurPathU != NULL) { free(FReq_InsCurPathU); FReq_InsCurPathU = NULL; } if (FReq_SmpCurPathU != NULL) { free(FReq_SmpCurPathU); FReq_SmpCurPathU = NULL; } if (FReq_PatCurPathU != NULL) { free(FReq_PatCurPathU); FReq_PatCurPathU = NULL; } if (FReq_TrkCurPathU != NULL) { free(FReq_TrkCurPathU); FReq_TrkCurPathU = NULL; } if (modTmpFNameUTF8 != NULL) { free(modTmpFNameUTF8); modTmpFNameUTF8 = NULL; } freeDirRecBuffer(); } bool setupDiskOp(void) { modTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); insTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); smpTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); patTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); trkTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); FReq_NameTemp = (char *)malloc((PATH_MAX + 1) * sizeof (char)); FReq_ModCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); FReq_InsCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); FReq_SmpCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); FReq_PatCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); FReq_TrkCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); if (modTmpFName == NULL || insTmpFName == NULL || smpTmpFName == NULL || patTmpFName == NULL || trkTmpFName == NULL || FReq_NameTemp == NULL || FReq_ModCurPathU == NULL || FReq_InsCurPathU == NULL || FReq_SmpCurPathU == NULL || FReq_PatCurPathU == NULL || FReq_TrkCurPathU == NULL) { // allocated memory is free'd lateron showErrorMsgBox("Not enough memory!"); return false; } // clear first entry of strings modTmpFName[0] = '\0'; insTmpFName[0] = '\0'; smpTmpFName[0] = '\0'; patTmpFName[0] = '\0'; trkTmpFName[0] = '\0'; FReq_NameTemp[0] = '\0'; FReq_ModCurPathU[0] = 0; FReq_InsCurPathU[0] = 0; FReq_SmpCurPathU[0] = 0; FReq_PatCurPathU[0] = 0; FReq_TrkCurPathU[0] = 0; strcpy(modTmpFName, "untitled.xm"); strcpy(insTmpFName, "untitled.xi"); strcpy(smpTmpFName, "untitled.wav"); strcpy(patTmpFName, "untitled.xp"); strcpy(trkTmpFName, "untitled.xt"); setupInitialPaths(); setDiskOpItem(0); updateCurrSongFilename(); // for window title updateWindowTitle(true); return true; } int32_t getExtOffset(char *s, int32_t stringLen) // get byte offset of file extension (last '.') { if (s == NULL || stringLen < 1) return -1; for (int32_t i = stringLen - 1; i >= 0; i--) { if (i != 0 && s[i] == '.') return i; } return -1; } static void removeQuestionmarksFromString(char *s) { if (s == NULL || *s == '\0') return; const int32_t len = (int32_t)strlen(s); for (int32_t i = 0; i < len; i++) { if (s[i] == '?') s[i] = ' ' ; } } #ifdef _WIN32 // WINDOWS SPECIFIC FILE OPERATION ROUTINES bool fileExistsAnsi(char *str) { UNICHAR *strU = cp437ToUnichar(str); if (strU == NULL) return false; bool retVal = PathFileExistsW(strU); free(strU); return retVal; } static bool deleteDirRecursive(UNICHAR *strU) { SHFILEOPSTRUCTW shfo; memset(&shfo, 0, sizeof (shfo)); shfo.wFunc = FO_DELETE; shfo.fFlags = FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMATION; shfo.pFrom = strU; return (SHFileOperationW(&shfo) == 0); } static bool makeDirAnsi(char *str) { UNICHAR *strU = cp437ToUnichar(str); if (strU == NULL) return false; int32_t retVal = _wmkdir(strU); free(strU); return (retVal == 0); } static bool renameAnsi(UNICHAR *oldNameU, char *newName) { UNICHAR *newNameU = cp437ToUnichar(newName); if (newNameU == NULL) return false; int32_t retVal = UNICHAR_RENAME(oldNameU, newNameU); free(newNameU); return (retVal == 0); } static void setupDiskOpDrives(void) // Windows only { fillRect(134, 29, 31, 111, PAL_DESKTOP); numLogicalDrives = 0; // get number of drives and drive names const uint32_t drivesBitmask = GetLogicalDrives(); for (int32_t i = 0; i < 8*sizeof (uint32_t); i++) { if ((drivesBitmask & (1 << i)) != 0) { driveIndexes[numLogicalDrives++] = i; if (numLogicalDrives == DISKOP_MAX_DRIVE_BUTTONS) break; } } // hide all buttons for (uint16_t i = 0; i < DISKOP_MAX_DRIVE_BUTTONS; i++) hidePushButton(PB_DISKOP_DRIVE1 + i); // set button names and show buttons for (uint16_t i = 0; i < numLogicalDrives; i++) { pushButtons[PB_DISKOP_DRIVE1 + i].caption = logicalDriveNames[driveIndexes[i]]; showPushButton(PB_DISKOP_DRIVE1 + i); } } static void openDrive(char *str) // Windows only { if (mouse.mode == MOUSE_MODE_DELETE) { okBox(8, "System complaint", "Very funny."); return; } if (str == NULL || *str == '\0') { okBox(0, "System message", "Couldn't open drive!"); return; } if (chdir(str) != 0) okBox(0, "System message", "Couldn't open drive! Please make sure there's a disk in it."); else editor.diskOpReadDir = true; } #else // NON-WINDOWS SPECIFIC FILE OPERATION ROUTINES bool fileExistsAnsi(char *str) { UNICHAR *strU = cp437ToUnichar(str); if (strU == NULL) return false; int32_t retVal = access(strU, F_OK); free(strU); return (retVal != -1); } static bool deleteDirRecursive(UNICHAR *strU)