#include "../cdb_system.h" #include struct sys_File_impl{ void * memory; HANDLE fileHandle; HANDLE fileMapHandle; }; //static void * internal_fileOpeninMem(HANDLE file){ // HANDLE fileMap = CreateFileMappingA(file, NULL, PAGE_READWRITE, 0, 0, NULL); //error if file is empty // if(fileMap == NULL || fileMap == INVALID_HANDLE_VALUE){ // return NULL; // } // void * memory = MapViewOfFile(fileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); // if(memory == NULL){ // CloseHandle(fileMap); // } // return memory; //} sys_File sys_fileOpenInMem(char * fileName, unsigned long parameter){ sys_File currentFile = sys_heapAlloc(sizeof(struct sys_File_impl)); if(currentFile == NULL) return NULL; currentFile->fileHandle = CreateFileA(fileName, GENERIC_READ | GENERIC_WRITE, //Open for reading and writing FILE_SHARE_READ, //It wouldn't be a good idea, if a different process wrote to the file at the same time NULL, (parameter & SYS_FILE_NEW ? CREATE_NEW : OPEN_EXISTING), //Open the file only if it exists/if it DOES NOT EXIST to prevent user error FILE_FLAG_RANDOM_ACCESS | //optimize for random access to file ((parameter & SYS_FILE_TEMP == SYS_FILE_TEMP) ? (FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE) : FILE_ATTRIBUTE_NORMAL), // just a normal file :D / automatically remove the file, if no longer needed NULL); if(currentFile->fileHandle == NULL || currentFile->fileHandle == INVALID_HANDLE_VALUE){ //debug //printf("Windows error: %i\n", GetLastError()); goto cleanup1; } //void * currentAdress = internal_fileOpeninMem(currentFile); //If the file is empty, there is nothing to map into memory, so this code puts something into the file if(GetFileSize(currentFile->fileHandle, NULL) == 0){ if(!WriteFile(currentFile->fileHandle, "", sizeof(""), NULL, NULL)){ goto cleanup2; } } currentFile->fileMapHandle = CreateFileMappingA(currentFile->fileHandle, NULL, PAGE_READWRITE, 0, 0, NULL); //error if file is empty if(currentFile->fileMapHandle == NULL || currentFile->fileMapHandle == INVALID_HANDLE_VALUE){ //return NULL; goto cleanup2; } currentFile->memory = MapViewOfFile(currentFile->fileMapHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0); if(currentFile->memory == NULL){ goto cleanup3; } return currentFile; //if(currentAdress == NULL){ // //cleanup // goto cleanup2; //} //return currentAdress; cleanup3: CloseHandle(currentFile->fileMapHandle); cleanup2: CloseHandle(currentFile->fileHandle); cleanup1: sys_heapFree(currentFile); return NULL; } //static void * internal_fileOpenInMem(char * fileName){ // HANDLE currentFile = CreateFileA(fileName, // GENERIC_READ | GENERIC_WRITE, //Open for reading and writing // FILE_SHARE_READ, //It wouldn't be a good idea, if a different process wrote to the file at the same time // NULL, // OPEN_EXISTING, //Open the file only if it exists to prevent user error // FILE_FLAG_RANDOM_ACCESS | //optimize for random access to file // FILE_ATTRIBUTE_NORMAL, // just a normal file :D // NULL); // if(currentFile == NULL || currentFile == INVALID_HANDLE_VALUE){ // return NULL; // } // void * currentAdress = internal_fileOpeninMem(currentFile); // if(currentAdress == NULL){ // //cleanup // CloseHandle(currentFile); // } // return currentAdress; //} // //static void * internal_fileOpenNewinMem(char * fileName){ // HANDLE currentFile = CreateFileA(fileName, // GENERIC_READ | GENERIC_WRITE, //Open for reading and writing // FILE_SHARE_READ, //It wouldn't be a good idea, if a different process wrote to the file at the same time // NULL, // CREATE_NEW, //Open the file only if it DOES NOT exist to prevent user error // FILE_FLAG_RANDOM_ACCESS | //optimize for random access to file // FILE_ATTRIBUTE_NORMAL, // just a normal file :D // NULL); // if(currentFile == NULL || currentFile == INVALID_HANDLE_VALUE){ // return NULL; // } // void * currentAdress = internal_fileOpeninMem(currentFile); // if(currentAdress == NULL){ // //cleanup // CloseHandle(currentFile); // } // return currentAdress; //} void * sys_fileFileToMemory(sys_File file){ return file->memory; } void sys_fileClose(sys_File file){ if(file->memory == NULL){ FlushViewOfFile(file->memory, 0); UnmapViewOfFile(file->memory); CloseHandle(file->fileMapHandle); CloseHandle(file->fileHandle); } sys_heapFree(file); } void sys_fileFlush(sys_File file){ FlushViewOfFile(file->memory, 0); } void sys_fileRename(char * fileName, char * newFileName){ MoveFile(fileName, newFileName); } void sys_fileDelete(char * fileName){ DeleteFile(fileName); } sys_Bool sys_fileExists(char * fileName){ DWORD fileAttributes = GetFileAttributes(fileName); return (fileAttributes == INVALID_FILE_ATTRIBUTES ? sys_True : sys_False); } void * sys_fileResize(sys_File file, signed long appendBytes){ FlushViewOfFile(file->memory, 0); UnmapViewOfFile(file->memory); CloseHandle(file->fileMapHandle); SetFilePointer(file->fileHandle, appendBytes, NULL, FILE_END); //Very cursed Unix style... SetEndOfFile(file->fileHandle); file->fileMapHandle = CreateFileMappingA(file->fileHandle, NULL, PAGE_READWRITE, 0, 0, NULL); //error if file is empty if(file->fileMapHandle == NULL || file->fileMapHandle == INVALID_HANDLE_VALUE){ //return NULL; goto cleanup2; } file->memory = MapViewOfFile(file->fileMapHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0); if(file->memory == NULL){ goto cleanup3; } return file->memory; cleanup3: CloseHandle(file->fileMapHandle); file->fileMapHandle = NULL; cleanup2: CloseHandle(file->fileHandle); file->fileHandle = NULL; //sys_heapFree(file); file->memory = NULL; return NULL; }