/** * @brief Get file status into member variables * * Reads file's status (size and full path). * @return true on success, false on failure. * @note Function sets filesize member to zero, and status as read * also when failing. That is needed so caller doesn't need to waste * time checking if file already exists (and ignores return value). */ bool UniLocalFile::DoGetFileStatus() { struct _stati64 fstats = {0}; m_statusFetched = -1; m_lastError.ClearError(); m_filepath = paths_GetLongPath(m_filepath.c_str()); if (_tstati64(m_filepath.c_str(), &fstats) == 0) { m_filesize = fstats.st_size; if (m_filesize == 0) { // if m_filesize equals zero, the file size is really zero or the file is a symbolic link. // use GetCompressedFileSize() to get the file size of the symbolic link target whether the file is symbolic link or not. // if the file is not symbolic link, GetCompressedFileSize() will return zero. // NOTE: GetCompressedFileSize() returns error for pre-W2K windows versions DWORD dwFileSizeLow, dwFileSizeHigh; dwFileSizeLow = GetCompressedFileSize(m_filepath.c_str(), &dwFileSizeHigh); if (GetLastError() == 0) m_filesize = ((__int64)dwFileSizeHigh << 32) + dwFileSizeLow; } m_statusFetched = 1; return true; } else { m_filesize = 0; m_statusFetched = 1; // Yep, done for this file still LastError(_T("_tstati64"), 0); return false; } }
void __fastcall TForm1::Button2Click(TObject *Sender) { if(this->OpenDialog1->Execute()) { AnsiString FileName = OpenDialog1->FileName ; int File = FileOpen(FileName,fmOpenRead); //获取文件内容真正的大小 int length = GetCompressedFileSize(FileName.c_str(),NULL); byte *buf = (byte *)malloc(length); char *content = (char *)malloc(length); //read file to buf FileRead(File,buf,length); FileSeek(File,0,0); FileRead(File,content,length); FileClose(File); this->MemoLeftData->Text = AnsiString(content); //store global data embeddata = BinaryToString(buf,length); embedSize = length * 8 ; free(content); free(buf); } }
_Success_( return != NULL ) ULONGLONG CFileFindWDS::GetCompressedLength( PCWSTR name ) const { /* Wrapper for file size retrieval This function tries to return compressed file size whenever possible. If the file is not compressed the uncompressed size is being returned. */ ULARGE_INTEGER ret; ret.QuadPart = 0;//it's a union, but I'm being careful. ret.LowPart = GetCompressedFileSize( name, &ret.HighPart ); if ( ( ret.LowPart == INVALID_FILE_SIZE ) ) { if ( ret.HighPart != NULL ) { if ( ( GetLastError( ) != NO_ERROR ) ) { return ret.QuadPart;// IN case of an error return size from CFileFind object } else { return GetLength( ); } } else if ( GetLastError( ) != NO_ERROR ) { #ifdef _DEBUG TRACE( _T( "Error (compressed file size)! Filepath: %s, Filepath length: %i, GetLastError: %s\r\n" ), altGetFilePath( ), altGetFilePath( ).GetLength( ), GetLastErrorAsFormattedMessage( ) ); #endif return GetLength( ); } } else { return ret.QuadPart; } ASSERT( false ); return NULL; }
File::filesize_t File::GetCompressedSize(StringIn filename) { DWORD hi; DWORD lo = GetCompressedFileSize(CStringw(filename), &hi); if (lo == INVALID_FILE_SIZE) { if (GetLastError()) { return 0; } } return lo | ((uint64)hi<<32); }
bool file::set_size(size_type s, error_code& ec) { TORRENT_ASSERT(is_open()); TORRENT_ASSERT(s >= 0); #ifdef TORRENT_WINDOWS LARGE_INTEGER offs; LARGE_INTEGER cur_size; if (GetFileSizeEx(m_file_handle, &cur_size) == FALSE) { ec = error_code(GetLastError(), get_system_category()); return false; } offs.QuadPart = s; // only set the file size if it's not already at // the right size. We don't want to update the // modification time if we don't have to if (cur_size.QuadPart != s) { if (SetFilePointerEx(m_file_handle, offs, &offs, FILE_BEGIN) == FALSE) { ec.assign(GetLastError(), get_system_category()); return false; } if (::SetEndOfFile(m_file_handle) == FALSE) { ec.assign(GetLastError(), get_system_category()); return false; } } #if _WIN32_WINNT >= 0x501 if ((m_open_mode & sparse) == 0) { // only allocate the space if the file // is not fully allocated DWORD high_dword = 0; offs.LowPart = GetCompressedFileSize(m_path.c_str(), &high_dword); offs.HighPart = high_dword; ec.assign(GetLastError(), get_system_category()); if (ec) return false; if (offs.QuadPart != s) { // if the user has permissions, avoid filling // the file with zeroes, but just fill it with // garbage instead SetFileValidData(m_file_handle, offs.QuadPart); } } #endif // _WIN32_WINNT >= 0x501 #else // NON-WINDOWS struct stat st; if (fstat(m_fd, &st) != 0) { ec.assign(errno, get_posix_category()); return false; } // only truncate the file if it doesn't already // have the right size. We don't want to update if (st.st_size != s && ftruncate(m_fd, s) < 0) { ec.assign(errno, get_posix_category()); return false; } // if we're not in sparse mode, allocate the storage // but only if the number of allocated blocks for the file // is less than the file size. Otherwise we would just // update the modification time of the file for no good // reason. if ((m_open_mode & sparse) == 0 && st.st_blocks < (s + st.st_blksize - 1) / st.st_blksize) { // How do we know that the file is already allocated? // if we always try to allocate the space, we'll update // the modification time without actually changing the file // but if we don't do anything if the file size is #ifdef F_PREALLOCATE fstore_t f = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, s, 0}; if (fcntl(m_fd, F_PREALLOCATE, &f) < 0) { ec = error_code(errno, get_posix_category()); return false; } #endif // F_PREALLOCATE #if defined TORRENT_LINUX || TORRENT_HAS_FALLOCATE int ret; #endif #if defined TORRENT_LINUX ret = my_fallocate(m_fd, 0, 0, s); // if we return 0, everything went fine // the fallocate call succeeded if (ret == 0) return true; // otherwise, something went wrong. If the error // is ENOSYS, just keep going and do it the old-fashioned // way. If fallocate failed with some other error, it // probably means the user should know about it, error out // and report it. if (errno != ENOSYS && errno != EOPNOTSUPP) { ec.assign(errno, get_posix_category()); return false; } #endif // TORRENT_LINUX #if TORRENT_HAS_FALLOCATE // if fallocate failed, we have to use posix_fallocate // which can be painfully slow // if you get a compile error here, you might want to // define TORRENT_HAS_FALLOCATE to 0. ret = posix_fallocate(m_fd, 0, s); // posix_allocate fails with EINVAL in case the underlying // filesystem does bot support this operation if (ret != 0 && ret != EINVAL) { ec = error_code(ret, get_posix_category()); return false; } #endif // TORRENT_HAS_FALLOCATE } #endif // TORRENT_WINDOWS return true; }
bool MapRemoteModule(unsigned long pId, char *module) { IMAGE_DOS_HEADER *dosHd; IMAGE_NT_HEADERS *ntHd; HANDLE hFile = CreateFile(module, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile == INVALID_HANDLE_VALUE) return false; unsigned int fSize; if(GetFileAttributes(module) & FILE_ATTRIBUTE_COMPRESSED) fSize = GetCompressedFileSize(module, NULL); else fSize = GetFileSize(hFile, NULL); unsigned char *dllBin = new unsigned char[fSize]; unsigned int nBytes; ReadFile(hFile, dllBin, fSize, (LPDWORD)&nBytes, FALSE); CloseHandle(hFile); // Every PE file contains a little DOS stub for backwards compatibility // it's only real relevance is that it contains a pointer to the actual // PE header. dosHd = MakePtr(IMAGE_DOS_HEADER *, dllBin, 0); // Make sure we got a valid DOS header if(dosHd->e_magic != IMAGE_DOS_SIGNATURE) { delete dllBin; printf("invalid dos header\n"); return false; } // Get the real PE header from the DOS stub header ntHd = MakePtr(IMAGE_NT_HEADERS *, dllBin, dosHd->e_lfanew); // Verify the PE header if(ntHd->Signature != IMAGE_NT_SIGNATURE) { delete dllBin; printf("invalid nt header\n"); return false; } HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId); if(!hProcess) { printf("open process failed\n"); return false; } // Allocate space for the module in the remote process void *moduleBase = VirtualAllocEx(hProcess, NULL, ntHd->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); // Make sure we got the memory space we wanted if(!moduleBase) { printf("virtual alloc failed (moduleBase)\n"); return false; } // Allocate space for our stub void *stubBase = VirtualAllocEx(hProcess, NULL, MakeDelta(SIZE_T, DC_stubend, DllCall_stub), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); // Make sure we got the memory space we wanted if(!stubBase) { printf("virtual alloc failed(stubBase)\n"); return false; } // Fix up the import table of the new module IMAGE_IMPORT_DESCRIPTOR *impDesc = (IMAGE_IMPORT_DESCRIPTOR *)GetPtrFromRVA( (DWORD)(ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress), ntHd, (PBYTE)dllBin); if(ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size) FixImports(pId, (unsigned char *)dllBin, ntHd, impDesc); // Fix "base relocations" of the new module. Base relocations are places // in the module that use absolute addresses to reference data. Since // the base address of the module can be different at different times, // the base relocation data is necessary to make the module loadable // at any address. IMAGE_BASE_RELOCATION *reloc = (IMAGE_BASE_RELOCATION *)GetPtrFromRVA( (DWORD)(ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress), ntHd, (PBYTE)dllBin); if(ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size) FixRelocs(dllBin, moduleBase, ntHd, reloc, ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size); // Write the PE header into the remote process's memory space WriteProcessMemory(hProcess, moduleBase, dllBin, ntHd->FileHeader.SizeOfOptionalHeader + sizeof(ntHd->FileHeader) + sizeof(ntHd->Signature), (SIZE_T *)&nBytes); // Map the sections into the remote process(they need to be aligned // along their virtual addresses) MapSections(hProcess, moduleBase, dllBin, ntHd); // Change the page protection on the DllCall_stub function from PAGE_EXECUTE_READ // to PAGE_EXECUTE_READWRITE, so we can patch it. VirtualProtect((LPVOID)DllCall_stub, MakeDelta(SIZE_T, DC_stubend, DllCall_stub), PAGE_EXECUTE_READWRITE, (DWORD *)&nBytes); // Patch the stub so it calls the correct address *MakePtr(unsigned long *, DllCall_stub, 9) = MakePtr(unsigned long, moduleBase, ntHd->OptionalHeader.AddressOfEntryPoint); // Write the stub into the remote process WriteProcessMemory(hProcess, stubBase, (LPVOID)DllCall_stub, MakeDelta(SIZE_T, DC_stubend, DllCall_stub), (SIZE_T *)&nBytes); // Execute our stub in the remote process CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)stubBase, moduleBase, // Pass the base address of the module as the argument to the stub. // All a module handle is, is the base address of the module(except // in windows CE), so we're really passing a handle to the module // so that it can refer to itself, create dialogs, etc.. 0, NULL); delete dllBin; return true; }
BOOL slimhelper::ScanFile(const CString& strFilePath, ULONGLONG qwFileSize, DWORD dwFileAttributes, ISystemSlimCallBack* piCallback) { BOOL retval = FALSE; HANDLE hFind = NULL; HRESULT hr; ULARGE_INTEGER tempSize; ULONGLONG qwSaveSize = 0; BOOL bCompressed = FALSE; if (!piCallback) goto clean0; if (INVALID_FILE_ATTRIBUTES == dwFileAttributes) { dwFileAttributes = GetFileAttributes(strFilePath); if (INVALID_FILE_ATTRIBUTES == dwFileAttributes) goto clean0; } if (dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED || dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) { bCompressed = TRUE; } if (bCompressed) { tempSize.LowPart = GetCompressedFileSize(strFilePath, &tempSize.HighPart); qwFileSize = tempSize.QuadPart; } else { if (0 == qwFileSize) { CAtlFile file; hr = file.Create( strFilePath, FILE_GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, OPEN_EXISTING ); if (FAILED(hr)) goto clean0; tempSize.LowPart = GetFileSize((HANDLE)file, &tempSize.HighPart); qwFileSize = tempSize.QuadPart; } } qwFileSize = FileSizeConver::Instance().FileSizeOnDisk(qwFileSize); piCallback->OnScanItem(strFilePath, qwFileSize, bCompressed); retval = TRUE; clean0: if (hFind) { FindClose(hFind); hFind = NULL; } return retval; }
BOOL slimhelper::RecyclePath(const CString& strFilePath, BOOL bKeepRootDir) { BOOL retval = FALSE; CString strOldSecurityDescriptor; HRESULT hr; int nRetCode; ULARGE_INTEGER tempSize; DWORD dwFileAttributes; BOOL bIsDir = FALSE; SHFILEOPSTRUCTW fileopt = { 0 }; ULONGLONG qwFileSize = 0; TCHAR* szDelPath = new TCHAR[MAX_PATH * 2]; CString strFlagFile; RtlZeroMemory(szDelPath, sizeof(TCHAR) * MAX_PATH * 2); StringCchCopy(szDelPath, MAX_PATH * 2, strFilePath); fileopt.pFrom = szDelPath; fileopt.wFunc = FO_DELETE; fileopt.fFlags = FOF_SILENT|FOF_NOCONFIRMATION|FOF_NOERRORUI|FOF_ALLOWUNDO; dwFileAttributes = ::GetFileAttributes(strFilePath); if (INVALID_FILE_ATTRIBUTES == dwFileAttributes) goto clean0; if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) bIsDir = TRUE; GrantFileAccess(strFilePath, strOldSecurityDescriptor, bIsDir); //if (!GrantFileAccess(strFilePath, strOldSecurityDescriptor)) // goto clean0; strFlagFile = strFilePath + _T("\\"); strFlagFile += g_kSlimFlag; if (bIsDir) { ::DeleteFile(strFlagFile); nRetCode = SHFileOperationW(&fileopt); if (32 == nRetCode) goto clean0; if (0x78 == nRetCode || 5 == nRetCode) { GrantDirAccess(strFilePath); ::DeleteFile(strFlagFile); nRetCode = SHFileOperationW(&fileopt);; } if (!nRetCode) { if (bKeepRootDir) { ::CreateDirectory(strFilePath, NULL); // 创建瘦身后的标记文件 // CAtlFile file; // file.Create(strFlagFile, // FILE_GENERIC_WRITE, // FILE_SHARE_READ|FILE_SHARE_WRITE, // CREATE_ALWAYS); } retval = TRUE; } goto clean0; } if (dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED || dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) { tempSize.LowPart = GetCompressedFileSize(strFilePath, &tempSize.HighPart); qwFileSize = tempSize.QuadPart; } else { CAtlFile file; hr = file.Create(strFilePath, FILE_GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, OPEN_EXISTING); if (FAILED(hr)) goto clean0; tempSize.LowPart = GetFileSize((HANDLE)file, &tempSize.HighPart); qwFileSize = tempSize.QuadPart; } qwFileSize = FileSizeConver::Instance().FileSizeOnDisk(qwFileSize); nRetCode = SHFileOperationW(&fileopt); if (nRetCode) goto clean0; retval = TRUE; clean0: if (szDelPath) { delete[] szDelPath; szDelPath = NULL; } return retval; }
////////////////////////////////////////////////////////////////////////// // 删除单个文件 BOOL slimhelper::DeleteFile(const CString& strFilePath, ULONGLONG qwFileSize, DWORD dwFileAttributes, ISystemSlimCallBack* piCallback) { BOOL retval = FALSE; BOOL bRetCode; CString strOldSecurityDescriptor; HRESULT hr; ULARGE_INTEGER tempSize; if (!piCallback) goto clean0; if (!piCallback->OnBeginProcessItem(strFilePath)) goto clean0; if (INVALID_FILE_ATTRIBUTES == dwFileAttributes) { dwFileAttributes = ::GetFileAttributes(strFilePath); if (INVALID_FILE_ATTRIBUTES == dwFileAttributes) goto clean0; } if (dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED || dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) { tempSize.LowPart = GetCompressedFileSize(strFilePath, &tempSize.HighPart); qwFileSize = tempSize.QuadPart; } else { if (0 == qwFileSize) { CAtlFile file; hr = file.Create(strFilePath, FILE_GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, OPEN_EXISTING); if (FAILED(hr)) goto clean0; tempSize.LowPart = GetFileSize((HANDLE)file, &tempSize.HighPart); qwFileSize = tempSize.QuadPart; } } qwFileSize = FileSizeConver::Instance().FileSizeOnDisk(qwFileSize); if (!GrantFileAccess(strFilePath, strOldSecurityDescriptor)) goto clean0; bRetCode = ::DeleteFile(strFilePath); if (!bRetCode) { if (!::MoveFileEx(strFilePath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT)) { goto clean0; } } piCallback->OnEndProcessItem(strFilePath, qwFileSize); retval = TRUE; clean0: return retval; }