static BOOL pendingRename() { static const WCHAR ValueName[] = {'P','e','n','d','i','n','g', 'F','i','l','e','R','e','n','a','m','e', 'O','p','e','r','a','t','i','o','n','s',0}; static const WCHAR SessionW[] = { 'S','y','s','t','e','m','\\', 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', 'C','o','n','t','r','o','l','\\', 'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r',0}; WCHAR *buffer=NULL; const WCHAR *src=NULL, *dst=NULL; DWORD dataLength=0; HKEY hSession=NULL; DWORD res; printf("Entered\n"); if ((res=RegOpenKeyExW(HKEY_LOCAL_MACHINE, SessionW, 0, KEY_ALL_ACCESS, &hSession)) !=ERROR_SUCCESS) { if (res==ERROR_FILE_NOT_FOUND) { printf("The key was not found - skipping\n"); res=TRUE; } else { printf("Couldn't open key, error %lu\n", res); res=FALSE; } goto end; } res=RegQueryValueExW(hSession, ValueName, NULL, NULL /* The value type does not really interest us, as it is not truely a REG_MULTI_SZ anyways */, NULL, &dataLength); if (res==ERROR_FILE_NOT_FOUND) { /* No value - nothing to do. Great! */ printf("Value not present - nothing to rename\n"); res=TRUE; goto end; } if (res!=ERROR_SUCCESS) { printf("Couldn't query value's length (%lu)\n", res); res=FALSE; goto end; } buffer=malloc(dataLength); if (buffer==NULL) { printf("Couldn't allocate %lu bytes for the value\n", dataLength); res=FALSE; goto end; } res=RegQueryValueExW(hSession, ValueName, NULL, NULL, (LPBYTE)buffer, &dataLength); if (res!=ERROR_SUCCESS) { printf("Couldn't query value after successfully querying before (%lu),\n" "please report to [email protected]\n", res); res=FALSE; goto end; } /* Make sure that the data is long enough and ends with two NULLs. This * simplifies the code later on. */ if (dataLength<2*sizeof(buffer[0]) || buffer[dataLength/sizeof(buffer[0])-1]!='\0' || buffer[dataLength/sizeof(buffer[0])-2]!='\0') { printf("Improper value format - doesn't end with NULL\n"); res=FALSE; goto end; } for(src=buffer; (src-buffer)*sizeof(src[0])<dataLength && *src!='\0'; src=dst+lstrlenW(dst)+1) { DWORD dwFlags=0; printf("processing next command\n"); dst=src+lstrlenW(src)+1; /* We need to skip the \??\ header */ if (src[0]=='\\' && src[1]=='?' && src[2]=='?' && src[3]=='\\') src+=4; if (dst[0]=='!') { dwFlags|=MOVEFILE_REPLACE_EXISTING; dst++; } if (dst[0]=='\\' && dst[1]=='?' && dst[2]=='?' && dst[3]=='\\') dst+=4; if (*dst!='\0') { /* Rename the file */ MoveFileExW(src, dst, dwFlags); } else { /* Delete the file or directory */ res = GetFileAttributesW (src); if (res != (DWORD)-1) { if ((res&FILE_ATTRIBUTE_DIRECTORY)==0) { /* It's a file */ DeleteFileW(src); } else { /* It's a directory */ RemoveDirectoryW(src); } } else { printf("couldn't get file attributes (%ld)\n", GetLastError()); } } } if ((res=RegDeleteValueW(hSession, ValueName))!=ERROR_SUCCESS) { printf("Error deleting the value (%lu)\n", GetLastError()); res=FALSE; } else res=TRUE; end: if (buffer!=NULL) free(buffer); if (hSession!=NULL) RegCloseKey(hSession); return res; }
/** * Runs an update process as the service using the SYSTEM account. * * @param argc The number of arguments in argv * @param argv The arguments normally passed to updater.exe * argv[0] must be the path to updater.exe * @param processStarted Set to TRUE if the process was started. * @return TRUE if the update process was run had a return code of 0. */ BOOL StartUpdateProcess(int argc, LPWSTR *argv, LPCWSTR installDir, BOOL &processStarted) { LOG(("Starting update process as the service in session 0.")); STARTUPINFO si = {0}; si.cb = sizeof(STARTUPINFO); si.lpDesktop = L"winsta0\\Default"; PROCESS_INFORMATION pi = {0}; // The updater command line is of the form: // updater.exe update-dir apply [wait-pid [callback-dir callback-path args]] LPWSTR cmdLine = MakeCommandLine(argc, argv); // If we're about to start the update process from session 0, // then we should not show a GUI. This only really needs to be done // on Vista and higher, but it's better to keep everything consistent // across all OS if it's of no harm. if (argc >= 2 ) { // Setting the desktop to blank will ensure no GUI is displayed si.lpDesktop = L""; si.dwFlags |= STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; } // We move the updater.ini file out of the way because we will handle // executing PostUpdate through the service. We handle PostUpdate from // the service because there are some per user things that happen that // can't run in session 0 which we run updater.exe in. // Once we are done running updater.exe we rename updater.ini back so // that if there were any errors the next updater.exe will run correctly. WCHAR updaterINI[MAX_PATH + 1]; WCHAR updaterINITemp[MAX_PATH + 1]; BOOL selfHandlePostUpdate = FALSE; // We use the updater.ini from the same directory as the updater.exe // because of background updates. if (PathGetSiblingFilePath(updaterINI, argv[0], L"updater.ini") && PathGetSiblingFilePath(updaterINITemp, argv[0], L"updater.tmp")) { selfHandlePostUpdate = MoveFileExW(updaterINI, updaterINITemp, MOVEFILE_REPLACE_EXISTING); } // Add an env var for MOZ_USING_SERVICE so the updater.exe can // do anything special that it needs to do for service updates. // Search in updater.cpp for more info on MOZ_USING_SERVICE. putenv(const_cast<char*>("MOZ_USING_SERVICE=1")); LOG(("Starting service with cmdline: %ls", cmdLine)); processStarted = CreateProcessW(argv[0], cmdLine, nullptr, nullptr, FALSE, CREATE_DEFAULT_ERROR_MODE, nullptr, nullptr, &si, &pi); // Empty value on putenv is how you remove an env variable in Windows putenv(const_cast<char*>("MOZ_USING_SERVICE=")); BOOL updateWasSuccessful = FALSE; if (processStarted) { // Wait for the updater process to finish LOG(("Process was started... waiting on result.")); DWORD waitRes = WaitForSingleObject(pi.hProcess, TIME_TO_WAIT_ON_UPDATER); if (WAIT_TIMEOUT == waitRes) { // We waited a long period of time for updater.exe and it never finished // so kill it. TerminateProcess(pi.hProcess, 1); } else { // Check the return code of updater.exe to make sure we get 0 DWORD returnCode; if (GetExitCodeProcess(pi.hProcess, &returnCode)) { LOG(("Process finished with return code %d.", returnCode)); // updater returns 0 if successful. updateWasSuccessful = (returnCode == 0); } else { LOG_WARN(("Process finished but could not obtain return code.")); } } CloseHandle(pi.hProcess); CloseHandle(pi.hThread); // Check just in case updater.exe didn't change the status from // applying. If this is the case we report an error. BOOL isApplying = FALSE; if (IsStatusApplying(argv[1], isApplying) && isApplying) { if (updateWasSuccessful) { LOG(("update.status is still applying even know update " " was successful.")); if (!WriteStatusFailure(argv[1], SERVICE_STILL_APPLYING_ON_SUCCESS)) { LOG_WARN(("Could not write update.status still applying on" " success error.")); } // Since we still had applying we know updater.exe didn't do its // job correctly. updateWasSuccessful = FALSE; } else { LOG_WARN(("update.status is still applying and update was not successful.")); if (!WriteStatusFailure(argv[1], SERVICE_STILL_APPLYING_ON_FAILURE)) { LOG_WARN(("Could not write update.status still applying on" " success error.")); } } } } else { DWORD lastError = GetLastError(); LOG_WARN(("Could not create process as current user, " "updaterPath: %ls; cmdLine: %ls. (%d)", argv[0], cmdLine, lastError)); } // Now that we're done with the update, restore back the updater.ini file // We use it ourselves, and also we want it back in case we had any type // of error so that the normal update process can use it. if (selfHandlePostUpdate) { MoveFileExW(updaterINITemp, updaterINI, MOVEFILE_REPLACE_EXISTING); // Only run the PostUpdate if the update was successful if (updateWasSuccessful && argc > 2) { LPCWSTR updateInfoDir = argv[1]; bool backgroundUpdate = IsUpdateBeingStaged(argc, argv); // Launch the PostProcess with admin access in session 0. This is // actually launching the post update process but it takes in the // callback app path to figure out where to apply to. // The PostUpdate process with user only access will be done inside // the unelevated updater.exe after the update process is complete // from the service. We don't know here which session to start // the user PostUpdate process from. // Note that we don't need to do this if we're just staging the // update in the background, as the PostUpdate step runs when // performing the replacing in that case. if (!backgroundUpdate) { LOG(("Launching post update process as the service in session 0.")); if (!LaunchWinPostProcess(installDir, updateInfoDir, true, nullptr)) { LOG_WARN(("The post update process could not be launched." " installDir: %ls, updateInfoDir: %ls", installDir, updateInfoDir)); } } } } free(cmdLine); return updateWasSuccessful; }
bool renameFile(const char* oldpath, const char* newpath) { return !!MoveFileExW(fromUtf8(oldpath).c_str(), fromUtf8(newpath).c_str(), MOVEFILE_REPLACE_EXISTING); }
/************************************************************************** * DelayedMove [SETUPAPI.@] * * Moves a file upon the next reboot. * * PARAMS * lpExistingFileName [I] Current file name * lpNewFileName [I] New file name * * RETURNS * Success: TRUE * Failure: FALSE */ BOOL WINAPI DelayedMove(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName) { return MoveFileExW(lpExistingFileName, lpNewFileName, MOVEFILE_REPLACE_EXISTING | MOVEFILE_DELAY_UNTIL_REBOOT); }
posix_errno_t efile_rename(const efile_path_t *old_path, const efile_path_t *new_path) { BOOL old_is_directory, new_is_directory; DWORD move_flags, last_error; ASSERT_PATH_FORMAT(old_path); ASSERT_PATH_FORMAT(new_path); move_flags = MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH; if(MoveFileExW((WCHAR*)old_path->data, (WCHAR*)new_path->data, move_flags)) { return 0; } last_error = GetLastError(); old_is_directory = has_file_attributes(old_path, FILE_ATTRIBUTE_DIRECTORY); new_is_directory = has_file_attributes(new_path, FILE_ATTRIBUTE_DIRECTORY); switch(last_error) { case ERROR_SHARING_VIOLATION: case ERROR_ACCESS_DENIED: if(old_is_directory) { BOOL moved_into_itself; moved_into_itself = (old_path->size <= new_path->size) && !_wcsnicmp((WCHAR*)old_path->data, (WCHAR*)new_path->data, PATH_LENGTH(old_path)); if(moved_into_itself) { return EINVAL; } else if(is_path_root(old_path)) { return EINVAL; } /* Renaming a directory across volumes needs to be rewritten as * EXDEV so that the caller can respond by simulating it with * copy/delete operations. * * Files are handled through MOVEFILE_COPY_ALLOWED. */ if(!has_same_mount_point(old_path, new_path)) { return EXDEV; } } break; case ERROR_PATH_NOT_FOUND: case ERROR_FILE_NOT_FOUND: return ENOENT; case ERROR_ALREADY_EXISTS: case ERROR_FILE_EXISTS: if(old_is_directory && !new_is_directory) { return ENOTDIR; } else if(!old_is_directory && new_is_directory) { return EISDIR; } else if(old_is_directory && new_is_directory) { /* This will fail if the destination isn't empty. */ if(RemoveDirectoryW((WCHAR*)new_path->data)) { return efile_rename(old_path, new_path); } return EEXIST; } else if(!old_is_directory && !new_is_directory) { /* This is pretty iffy; the public documentation says that the * operation may EACCES on some systems when either file is open, * which gives us room to use MOVEFILE_REPLACE_EXISTING and be done * with it, but the old implementation simulated Unix semantics and * there's a lot of code that relies on that. * * The simulation renames the destination to a scratch name to get * around the fact that it's impossible to open (and by extension * rename) a file that's been deleted while open. It has a few * drawbacks though; * * 1) It's not atomic as there's a small window where there's no * file at all on the destination path. * 2) It will confuse applications that subscribe to folder * changes. * 3) It will fail if we lack general permission to write in the * same folder. */ WCHAR *swap_path = enif_alloc(new_path->size + sizeof(WCHAR) * 64); if(swap_path == NULL) { return ENOMEM; } else { static LONGLONG unique_counter = 0; WCHAR *swap_path_end; /* We swap in the same folder as the destination to be * reasonably sure that it's on the same volume. Note that * we're avoiding GetTempFileNameW as it will fail on long * paths. */ sys_memcpy(swap_path, (WCHAR*)new_path->data, new_path->size); swap_path_end = swap_path + PATH_LENGTH(new_path); while(!IS_SLASH(*swap_path_end)) { ASSERT(swap_path_end > swap_path); swap_path_end--; } StringCchPrintfW(&swap_path_end[1], 64, L"erl-%lx-%llx.tmp", GetCurrentProcessId(), unique_counter); InterlockedIncrement64(&unique_counter); } if(MoveFileExW((WCHAR*)new_path->data, swap_path, MOVEFILE_REPLACE_EXISTING)) { if(MoveFileExW((WCHAR*)old_path->data, (WCHAR*)new_path->data, move_flags)) { last_error = ERROR_SUCCESS; DeleteFileW(swap_path); } else { last_error = GetLastError(); MoveFileW(swap_path, (WCHAR*)new_path->data); } } else { last_error = GetLastError(); DeleteFileW(swap_path); } enif_free(swap_path); return windows_to_posix_errno(last_error); } return EEXIST; } return windows_to_posix_errno(last_error); }
/** * Installs or upgrades the SVC_NAME service. * If an existing service is already installed, we replace it with the * currently running process. * * @param action The action to perform. * @return TRUE if the service was installed/upgraded */ BOOL SvcInstall(SvcInstallAction action) { // Get a handle to the local computer SCM database with full access rights. nsAutoServiceHandle schSCManager(OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)); if (!schSCManager) { LOG(("Could not open service manager. (%d)\n", GetLastError())); return FALSE; } WCHAR newServiceBinaryPath[MAX_PATH + 1]; if (!GetModuleFileNameW(NULL, newServiceBinaryPath, sizeof(newServiceBinaryPath) / sizeof(newServiceBinaryPath[0]))) { LOG(("Could not obtain module filename when attempting to " "install service. (%d)\n", GetLastError())); return FALSE; } // Check if we already have the service installed. nsAutoServiceHandle schService(OpenServiceW(schSCManager, SVC_NAME, SERVICE_ALL_ACCESS)); DWORD lastError = GetLastError(); if (!schService && ERROR_SERVICE_DOES_NOT_EXIST != lastError) { // The service exists but we couldn't open it LOG(("Could not open service. (%d)\n", GetLastError())); return FALSE; } if (schService) { // The service exists but it may not have the correct permissions. // This could happen if the permissions were not set correctly originally // or have been changed after the installation. This will reset the // permissions back to allow limited user accounts. if (!SetUserAccessServiceDACL(schService)) { LOG(("Could not reset security ACE on service handle. It might not be " "possible to start the service. This error should never " "happen. (%d)\n", GetLastError())); } // The service exists and we opened it DWORD bytesNeeded; if (!QueryServiceConfigW(schService, NULL, 0, &bytesNeeded) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { LOG(("Could not determine buffer size for query service config. (%d)\n", GetLastError())); return FALSE; } // Get the service config information, in particular we want the binary // path of the service. nsAutoArrayPtr<char> serviceConfigBuffer = new char[bytesNeeded]; if (!QueryServiceConfigW(schService, reinterpret_cast<QUERY_SERVICE_CONFIGW*>(serviceConfigBuffer.get()), bytesNeeded, &bytesNeeded)) { LOG(("Could open service but could not query service config. (%d)\n", GetLastError())); return FALSE; } QUERY_SERVICE_CONFIGW &serviceConfig = *reinterpret_cast<QUERY_SERVICE_CONFIGW*>(serviceConfigBuffer.get()); // Check if we need to fix the service path BOOL servicePathWasWrong; static BOOL alreadyCheckedFixServicePath = FALSE; if (!alreadyCheckedFixServicePath) { if (!FixServicePath(schService, serviceConfig.lpBinaryPathName, servicePathWasWrong)) { LOG(("Could not fix service path. This should never happen. (%d)\n", GetLastError())); // True is returned because the service is pointing to // maintenanceservice_tmp.exe so it actually was upgraded to the // newest installed service. return TRUE; } else if (servicePathWasWrong) { // Now that the path is fixed we should re-attempt the install. // This current process' image path is maintenanceservice_tmp.exe. // The service used to point to maintenanceservice_tmp.exe. // The service was just fixed to point to maintenanceservice.exe. // Re-attempting an install from scratch will work as normal. alreadyCheckedFixServicePath = TRUE; LOG(("Restarting install action: %d\n", action)); return SvcInstall(action); } } // Ensure the service path is not quoted. We own this memory and know it to // be large enough for the quoted path, so it is large enough for the // unquoted path. This function cannot fail. PathUnquoteSpacesW(serviceConfig.lpBinaryPathName); // Obtain the existing maintenanceservice file's version number and // the new file's version number. Versions are in the format of // A.B.C.D. DWORD existingA, existingB, existingC, existingD; DWORD newA, newB, newC, newD; BOOL obtainedExistingVersionInfo = GetVersionNumberFromPath(serviceConfig.lpBinaryPathName, existingA, existingB, existingC, existingD); if (!GetVersionNumberFromPath(newServiceBinaryPath, newA, newB, newC, newD)) { LOG(("Could not obtain version number from new path\n")); return FALSE; } // Check if we need to replace the old binary with the new one // If we couldn't get the old version info then we assume we should // replace it. if (ForceInstallSvc == action || !obtainedExistingVersionInfo || (existingA < newA) || (existingA == newA && existingB < newB) || (existingA == newA && existingB == newB && existingC < newC) || (existingA == newA && existingB == newB && existingC == newC && existingD < newD)) { // We have a newer updater, so update the description from the INI file. UpdateServiceDescription(schService); schService.reset(); if (!StopService()) { return FALSE; } if (!wcscmp(newServiceBinaryPath, serviceConfig.lpBinaryPathName)) { LOG(("File is already in the correct location, no action needed for " "upgrade. The path is: \"%ls\"\n", newServiceBinaryPath)); return TRUE; } BOOL result = TRUE; // Attempt to copy the new binary over top the existing binary. // If there is an error we try to move it out of the way and then // copy it in. First try the safest / easiest way to overwrite the file. if (!CopyFileW(newServiceBinaryPath, serviceConfig.lpBinaryPathName, FALSE)) { LOG(("Could not overwrite old service binary file. " "This should never happen, but if it does the next upgrade will " "fix it, the service is not a critical component that needs to be " "installed for upgrades to work. (%d)\n", GetLastError())); // We rename the last 3 filename chars in an unsafe way. Manually // verify there are more than 3 chars for safe failure in MoveFileExW. const size_t len = wcslen(serviceConfig.lpBinaryPathName); if (len > 3) { // Calculate the temp file path that we're moving the file to. This // is the same as the proper service path but with a .old extension. LPWSTR oldServiceBinaryTempPath = new WCHAR[len + 1]; memset(oldServiceBinaryTempPath, 0, (len + 1) * sizeof (WCHAR)); wcsncpy(oldServiceBinaryTempPath, serviceConfig.lpBinaryPathName, len); // Rename the last 3 chars to 'old' wcsncpy(oldServiceBinaryTempPath + len - 3, L"old", 3); // Move the current (old) service file to the temp path. if (MoveFileExW(serviceConfig.lpBinaryPathName, oldServiceBinaryTempPath, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) { // The old binary is moved out of the way, copy in the new one. if (!CopyFileW(newServiceBinaryPath, serviceConfig.lpBinaryPathName, FALSE)) { // It is best to leave the old service binary in this condition. LOG(("ERROR: The new service binary could not be copied in." " The service will not be upgraded.\n")); result = FALSE; } else { LOG(("The new service binary was copied in by first moving the" " old one out of the way.\n")); } // Attempt to get rid of the old service temp path. if (DeleteFileW(oldServiceBinaryTempPath)) { LOG(("The old temp service path was deleted: %ls.\n", oldServiceBinaryTempPath)); } else { // The old temp path could not be removed. It will be removed // the next time the user can't copy the binary in or on uninstall. LOG(("WARNING: The old temp service path was not deleted.\n")); } } else { // It is best to leave the old service binary in this condition. LOG(("ERROR: Could not move old service file out of the way from:" " \"%ls\" to \"%ls\". Service will not be upgraded. (%d)\n", serviceConfig.lpBinaryPathName, oldServiceBinaryTempPath, GetLastError())); result = FALSE; } delete[] oldServiceBinaryTempPath; } else { // It is best to leave the old service binary in this condition. LOG(("ERROR: Service binary path was less than 3, service will" " not be updated. This should never happen.\n")); result = FALSE; } } else { LOG(("The new service binary was copied in.\n")); } // We made a copy of ourselves to the existing location. // The tmp file (the process of which we are executing right now) will be // left over. Attempt to delete the file on the next reboot. if (MoveFileExW(newServiceBinaryPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT)) { LOG(("Deleting the old file path on the next reboot: %ls.\n", newServiceBinaryPath)); } else { LOG(("Call to delete the old file path failed: %ls.\n", newServiceBinaryPath)); } return result; } // We don't need to copy ourselves to the existing location. // The tmp file (the process of which we are executing right now) will be // left over. Attempt to delete the file on the next reboot. MoveFileExW(newServiceBinaryPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); // nothing to do, we already have a newer service installed return TRUE; } // If the service does not exist and we are upgrading, don't install it. if (UpgradeSvc == action) { // The service does not exist and we are upgrading, so don't install it return TRUE; } // Quote the path only if it contains spaces. PathQuoteSpacesW(newServiceBinaryPath); // The service does not already exist so create the service as on demand schService.own(CreateServiceW(schSCManager, SVC_NAME, SVC_DISPLAY_NAME, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, newServiceBinaryPath, NULL, NULL, NULL, NULL, NULL)); if (!schService) { LOG(("Could not create Windows service. " "This error should never happen since a service install " "should only be called when elevated. (%d)\n", GetLastError())); return FALSE; } if (!SetUserAccessServiceDACL(schService)) { LOG(("Could not set security ACE on service handle, the service will not " "be able to be started from unelevated processes. " "This error should never happen. (%d)\n", GetLastError())); } UpdateServiceDescription(schService); return TRUE; }
int CDownloadThread::DownLoadBreakpointFile() { DWORD dwBytesRead = 0; char szReadBuf[1024]; DWORD dwBytesToRead = sizeof(szReadBuf); wchar_t wcsNum[255]; DWORD dwRegType = 0, dwReturnSize = sizeof(wcsNum), dwFilePoint; UINT64 uI64Num = 0; bool bIsBreak = false; uI64Num = IsBreakPointFile(m_wcsBreakFileName.c_str()); dwFilePoint = (DWORD)(uI64Num); if( dwFilePoint > 0 )//续传文件 { NEED_STOP; bIsBreak = true; m_hSaveFile = CreateFile(m_wcsBreakFileName.c_str(), MYWIRTEFILE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (m_hSaveFile == INVALID_HANDLE_VALUE)//断点文件不存在 { m_hSaveFile = CreateFile(m_wcsBreakFileName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); } else { if(INVALID_SET_FILE_POINTER == SetFilePointer(m_hSaveFile,dwFilePoint,NULL,FILE_BEGIN) ) { CRecordProgram::GetInstance()->FeedbackError(MY_ERROR_PRO_CORE, ERR_SETFILEPOINTER, CRecordProgram::GetInstance()->GetRecordInfo(L"DownLoadBreakpointFile的SetFilePointer异常!LastErrCode = %d", GetLastError())); CloseHandles(); return ERR_SETFILEPOINTER; } m_ui64TotalRead = dwFilePoint; } } else//重新下载 { NEED_STOP; m_hSaveFile = CreateFile(m_wcsBreakFileName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); } if ( INVALID_HANDLE_VALUE == m_hSaveFile ) { CRecordProgram::GetInstance()->FeedbackError(MY_ERROR_PRO_CORE, ERR_CREATEFILE, CRecordProgram::GetInstance()->GetRecordInfo(L"DownLoadBreakpointFile的CreateFile异常!LastErrCode = %d", GetLastError())); CloseHandles(); CloseHandles(); return ERR_CREATEFILE; } do { NEED_STOP; if (!::InternetReadFile(m_hInetFile, szReadBuf, dwBytesToRead, &dwBytesRead)) { CloseHandles(); if(m_repeatNum < REPEATNUM) { m_repeatNum ++; m_bRetryWait = true; // 重试等待 // 等待十秒后重试 int nTemp = 50; while(nTemp >= 0) { nTemp --; Sleep(200); NEED_STOP; } m_bRetryWait = false; CRecordProgram::GetInstance()->FeedbackError(MY_ERROR_PRO_CORE, ERR_INTREADFILE, CRecordProgram::GetInstance()->GetRecordInfo(L"DownLoadBreakpointFile中的InternetReadFile异常!LastErrCode = %d", GetLastError())); return this->TransferDataGet() == 0 ? false:true ; } else { CRecordProgram::GetInstance()->FeedbackError(MY_ERROR_PRO_CORE, ERR_OUTOFTIME, CRecordProgram::GetInstance()->GetRecordInfo(L"DownLoadBreakpointFile下载超时!LastErrCode = %d", GetLastError())); return ERR_OUTOFTIME; // 下载超时 } } else if (dwBytesRead) { DWORD dwBytesWritten = 0; if (!WriteFile(m_hSaveFile, szReadBuf, dwBytesRead, &dwBytesWritten, NULL)) { CRecordProgram::GetInstance()->FeedbackError(MY_ERROR_PRO_CORE, ERR_WRITEFILE, CRecordProgram::GetInstance()->GetRecordInfo(L"DownLoadBreakpointFile的WriteFile异常!LastErrCode = %d", GetLastError())); CloseHandles(); return ERR_WRITEFILE; } m_ui64TotalRead += dwBytesRead; } } while (dwBytesRead); CloseHandles(); NEED_STOP; if( !MoveFileExW(m_wcsBreakFileName.c_str(), m_strSaveFile.c_str() , MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED ) ) { CRecordProgram::GetInstance()->FeedbackError(MY_ERROR_PRO_CORE, ERR_RENAMEFILE, CRecordProgram::GetInstance()->GetRecordInfo(L"DownLoadBreakpointFile的MoveFileExW异常!LastErrCode = %d", GetLastError())); NEED_STOP; } m_wcsBreakFileName.clear (); return ERR_SUCCESS; }
int Rwin_wrename(const wchar_t *from, const wchar_t *to) { return (MoveFileExW(from, to, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH) == 0); }
void LogSessionAndSendNetmailToLink(lpFTNAddr lpLinkAddr, unsigned char SoftwareCode) { SQLHDBC hdbc; SQLHSTMT hstmt; SQLRETURN sqlret; SQLLEN cb; HANDLE hHeap; HANDLE hPktFile; wchar_t tmpPktFileName[MAX_PATH], finalPktFileName[MAX_PATH], FileboxDirName[MAX_PATH]; wchar_t LogStr[255]; unsigned int PktNumber; unsigned int LinkID; NetmailOutQueue NOQ; char PktPwd[9]; hHeap = HeapCreate(HEAP_NO_SERIALIZE, 16384, 0); SQLAllocHandle(SQL_HANDLE_DBC, cfg.henv, &hdbc); sqlret = SQLDriverConnectW(hdbc, NULL, cfg.ConnectionString, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT); if (sqlret != SQL_SUCCESS && sqlret != SQL_SUCCESS_WITH_INFO) { SetEvent(cfg.hExitEvent); return; //fatal error } SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); SQLBindParameter(hstmt, 1, SQL_PARAM_OUTPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &LinkID, 0, NULL); SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(lpLinkAddr->zone), 0, NULL); SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(lpLinkAddr->net), 0, NULL); SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(lpLinkAddr->node), 0, NULL); SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(lpLinkAddr->point), 0, NULL); SQLBindParameter(hstmt, 6, SQL_PARAM_INPUT, SQL_C_UTINYINT , SQL_TINYINT, 0, 0, &SoftwareCode, 0, NULL); SQLExecDirectW(hstmt, L"{?=call sp_GetLinkIdForNetmailRouting(?,?,?,?,?)}", SQL_NTS); NOQ.First = NULL; NOQ.Last = NULL; SQLFreeStmt(hstmt, SQL_RESET_PARAMS); if (SoftwareCode != 1) goto exit; if (LinkID != 0) { //netmail out// memset(PktPwd, 0, 9); SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &LinkID, 0, NULL); sqlret = SQLExecDirectW(hstmt, L"select PktPassword from Links where LinkID=?", SQL_NTS);// if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { sqlret = SQLFetch(hstmt); if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { SQLGetData(hstmt, 1, SQL_C_CHAR, PktPwd, 9, &cb); } } SQLCloseCursor(hstmt); EnterCriticalSection(&NetmailRouteCritSect); sqlret = SQLExecDirectW(hstmt, L"select Netmail.MessageID,FromZone,FromNet,FromNode,FromPoint,ToZone,ToNet,ToNode,ToPoint,CreateTime,FromName,ToName,Subject,MsgId,ReplyTo,MsgText,KillSent,Pvt,FileAttach,Arq,RRq,ReturnReq,Direct,Cfm,recv from Netmail,NetmailOutbound where Netmail.MessageID=NetmailOutbound.MessageID and NetmailOutbound.ToLinkID=? order by Netmail.MessageID", SQL_NTS);// if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { GetNetmailMessages(hstmt, hHeap, &NOQ); } SQLFreeStmt(hstmt, SQL_RESET_PARAMS); if (NOQ.First != NULL) { PktNumber = GetPktNumber(hstmt); wsprintfW(FileboxDirName, L"%s\\%u.%u.%u.0", cfg.FileboxesDir, lpLinkAddr->zone, lpLinkAddr->net, lpLinkAddr->node); wsprintfW(tmpPktFileName, L"%s\\%08X.NETMAIL", cfg.TmpOutboundDir, PktNumber); wsprintfW(finalPktFileName, L"%s\\%08X.PKT", FileboxDirName, PktNumber); hPktFile = CreateFileW(tmpPktFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL); WritePktHeader(hPktFile, &(cfg.MyAddr),lpLinkAddr, PktPwd); // while (NOQ.First != NULL) { lpNetmailMessage lpTmp; // wsprintfW(LogStr, L"Dynamic netmail %u:%u/%u.%u -> %u:%u/%u.%u thru %u:%u/%u", NOQ.First->FromAddr.zone, NOQ.First->FromAddr.net, NOQ.First->FromAddr.node, NOQ.First->FromAddr.point, NOQ.First->ToAddr.zone, NOQ.First->ToAddr.net, NOQ.First->ToAddr.node, NOQ.First->ToAddr.point, lpLinkAddr->zone, lpLinkAddr->net, lpLinkAddr->node); AddLogEntry(LogStr); WriteNetmailMessage(hPktFile, hHeap, NOQ.First); SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &(NOQ.First->MessageID), 0, NULL); sqlret = SQLExecDirectW(hstmt, L"{call sp_NetmailMessageSent(?)}", SQL_NTS); SQLFreeStmt(hstmt, SQL_RESET_PARAMS); // lpTmp = NOQ.First->NextMsg; HeapFree(hHeap, 0, NOQ.First->MsgText); if (NOQ.First->ReplyTo != NULL) HeapFree(hHeap, 0, NOQ.First->ReplyTo); if (NOQ.First->MsgId != NULL) HeapFree(hHeap, 0, NOQ.First->MsgId); HeapFree(hHeap, 0, NOQ.First->Subject); HeapFree(hHeap, 0, NOQ.First->ToName); HeapFree(hHeap, 0, NOQ.First->FromName); HeapFree(hHeap, 0, NOQ.First); NOQ.First = lpTmp; } if (hPktFile != INVALID_HANDLE_VALUE) { ClosePktFile(hPktFile); CreateDirectoryW(FileboxDirName, NULL); MoveFileExW(tmpPktFileName, finalPktFileName, MOVEFILE_COPY_ALLOWED); } // } LeaveCriticalSection(&NetmailRouteCritSect); } exit: SQLFreeHandle(SQL_HANDLE_STMT, hstmt); SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); HeapDestroy(hHeap); }
DWORD WINAPI NetmailOutThread(LPVOID param) { SQLHDBC hdbc; SQLHSTMT hstmt; SQLRETURN sqlret; SQLLEN cb; HANDLE hHeap; FTNAddr LastAddr; HANDLE hPktFile; wchar_t tmpFileName[MAX_PATH], finalPktFileName[MAX_PATH],FileboxDirName[MAX_PATH]; wchar_t LogStr[255]; unsigned int PktNumber; char PktPwd[9]; NetmailOutQueue NDOQ; int WaitTime; int result; HANDLE hEvent[2]; InterlockedIncrement(&(cfg.ThreadCount)); WaitTime=INFINITE; hEvent[0]=cfg.hExitEvent; hEvent[1]=cfg.hNetmailOutEvent; AddLogEntry(L"Netmail out thread started"); loop: result=WaitForMultipleObjects(2,hEvent,FALSE,WaitTime); if (result==WAIT_TIMEOUT) { SQLFreeHandle(SQL_HANDLE_STMT,hstmt); SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC,hdbc); WaitTime=INFINITE; HeapDestroy(hHeap); goto loop; } if (WaitTime==INFINITE) { hHeap=HeapCreate(HEAP_NO_SERIALIZE,16384,0); SQLAllocHandle(SQL_HANDLE_DBC, cfg.henv, &hdbc); sqlret=SQLDriverConnectW(hdbc, NULL, cfg.ConnectionString, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT); if (sqlret != SQL_SUCCESS && sqlret != SQL_SUCCESS_WITH_INFO) { SetEvent(cfg.hExitEvent); goto threadexit; //fatal error } SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); WaitTime=10000; } switch(result) { case (WAIT_OBJECT_0): { goto threadexit; } case (WAIT_OBJECT_0+1): { NDOQ.First=NULL; NDOQ.Last=NULL; EnterCriticalSection(&NetmailRouteCritSect); SQLExecDirectW(hstmt, L"execute sp_DirectNetmail", SQL_NTS); // обработать директный нетмейл для использующих FTN Service линков LeaveCriticalSection(&NetmailRouteCritSect); sqlret=SQLExecDirectW(hstmt,L"select MessageID,FromZone,FromNet,FromNode,FromPoint,ToZone,ToNet,ToNode,ToPoint,CreateTime,FromName,ToName,Subject,MsgId,ReplyTo,MsgText,KillSent,Pvt,FileAttach,Arq,RRq,ReturnReq,Direct,Cfm,recv from Netmail where direct=1 and sent=0 and Locked=0 order by ToZone,ToNet,ToNode,MessageID",SQL_NTS); if ((sqlret==SQL_SUCCESS)||(sqlret==SQL_SUCCESS_WITH_INFO)) { GetNetmailMessages(hstmt,hHeap,&NDOQ); } sqlret=SQLExecDirectW(hstmt,L"select MessageID,FromZone,FromNet,FromNode,FromPoint,ToZone,ToNet,ToNode,ToPoint,CreateTime,FromName,ToName,Subject,MsgId,ReplyTo,MsgText,KillSent,Pvt,FileAttach,Arq,RRq,ReturnReq,Direct,Cfm,recv from Netmail,MyAka where direct=0 and sent=0 and Locked=0 and MyAka.Point=0 and Netmail.ToPoint<>0 and Netmail.ToZone=MyAka.Zone and Netmail.ToNet=MyAka.Net and Netmail.ToNode=MyAka.Node order by ToPoint,MessageID",SQL_NTS); if ((sqlret==SQL_SUCCESS)||(sqlret==SQL_SUCCESS_WITH_INFO)) { GetNetmailMessages(hstmt, hHeap, &NDOQ); } sqlret = SQLExecDirectW(hstmt, L"select MessageID,FromZone,FromNet,FromNode,FromPoint,ToZone,ToNet,ToNode,ToPoint,CreateTime,FromName,ToName,Subject,MsgId,ReplyTo,MsgText,KillSent,Pvt,FileAttach,Arq,RRq,ReturnReq,Direct,Cfm,recv from Netmail,Links where direct=0 and sent=0 and Locked=0 and Netmail.ToZone=Links.Zone and Netmail.ToNet=Links.Net and Netmail.ToNode=Links.Node and Links.NetmailDirect<>0 and Links.LinkType=2 order by Links.LinkID,MessageID", SQL_NTS); if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { GetNetmailMessages(hstmt, hHeap, &NDOQ); } LastAddr.FullAddr=0; hPktFile=INVALID_HANDLE_VALUE; while (NDOQ.First!=NULL) { lpNetmailMessage lpTmp; wsprintfW(LogStr,L"Direct netmail From %u:%u/%u.%u To %u:%u/%u.%u",NDOQ.First->FromAddr.zone,NDOQ.First->FromAddr.net,NDOQ.First->FromAddr.node,NDOQ.First->FromAddr.point,NDOQ.First->ToAddr.zone,NDOQ.First->ToAddr.net,NDOQ.First->ToAddr.node,NDOQ.First->ToAddr.point); AddLogEntry(LogStr); if (LastAddr.FullAddr!=NDOQ.First->ToAddr.FullAddr) { if(LastAddr.FullAddr!=0) { ClosePktFile(hPktFile); CreateDirectoryW(FileboxDirName,NULL); MoveFileExW(tmpFileName,finalPktFileName,MOVEFILE_COPY_ALLOWED); } LastAddr.FullAddr=NDOQ.First->ToAddr.FullAddr; //create file PktNumber=GetPktNumber(hstmt); wsprintfW(FileboxDirName, L"%s\\%u.%u.%u.%u", cfg.FileboxesDir, NDOQ.First->ToAddr.zone, NDOQ.First->ToAddr.net, NDOQ.First->ToAddr.node, NDOQ.First->ToAddr.point); wsprintfW(tmpFileName, L"%s\\%08X.NETMAIL", cfg.TmpOutboundDir, PktNumber); wsprintfW(finalPktFileName,L"%s\\%08X.PKT",FileboxDirName,PktNumber); hPktFile=CreateFileW(tmpFileName,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_NEW,0,NULL); memset(PktPwd, 0, 9); SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(NDOQ.First->ToAddr.zone), 0, NULL); SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(NDOQ.First->ToAddr.net), 0, NULL); SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(NDOQ.First->ToAddr.node), 0, NULL); SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(NDOQ.First->ToAddr.point), 0, NULL); sqlret = SQLExecDirectW(hstmt, L"Select PktPassword from Links where Zone=? and Net=? and Node=? and Point=?", SQL_NTS); if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { sqlret = SQLFetch(hstmt); if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { SQLGetData(hstmt, 1, SQL_C_CHAR, PktPwd, 9, &cb); } } SQLCloseCursor(hstmt); SQLFreeStmt(hstmt, SQL_RESET_PARAMS); WritePktHeader(hPktFile,&(cfg.MyAddr),&(NDOQ.First->ToAddr),PktPwd); } // WriteNetmailMessage(hPktFile,hHeap,NDOQ.First); // SQLBindParameter(hstmt,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&(NDOQ.First->MessageID),0,NULL); sqlret=SQLExecDirectW(hstmt,L"{call sp_NetmailMessageSent(?)}",SQL_NTS); SQLFreeStmt(hstmt,SQL_RESET_PARAMS); // lpTmp=NDOQ.First->NextMsg; HeapFree(hHeap,0,NDOQ.First->MsgText); if (NDOQ.First->ReplyTo!=NULL) HeapFree(hHeap,0,NDOQ.First->ReplyTo); if (NDOQ.First->MsgId!=NULL) HeapFree(hHeap,0,NDOQ.First->MsgId); HeapFree(hHeap,0,NDOQ.First->Subject); HeapFree(hHeap,0,NDOQ.First->ToName); HeapFree(hHeap,0,NDOQ.First->FromName); HeapFree(hHeap,0,NDOQ.First); NDOQ.First=lpTmp; } if (hPktFile!=INVALID_HANDLE_VALUE) { ClosePktFile(hPktFile); CreateDirectoryW(FileboxDirName,NULL); MoveFileExW(tmpFileName,finalPktFileName,MOVEFILE_COPY_ALLOWED); } // EnterCriticalSection(&NetmailRouteCritSect); SQLExecDirectW(hstmt, L"EXECUTE sp_RouteNetmail",SQL_NTS); LeaveCriticalSection(&NetmailRouteCritSect); SetEvent(cfg.hMailerCallGeneratingEvent); //make polls sqlret = SQLExecDirectW(hstmt, L"select Zone,Net,Node from Links,NetmailOutbound,Netmail where Links.LinkID=NetmailOutbound.ToLinkID and Netmail.MessageID=NetmailOutbound.MessageID and Netmail.Locked=0 and Links.DialOut<>0 and Links.LinkType<=2 and Links.Point=0", SQL_NTS); if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { unsigned short zone, net, node; SQLBindCol(hstmt, 1, SQL_C_USHORT, &zone, 0, NULL); SQLBindCol(hstmt, 2, SQL_C_USHORT, &net, 0, NULL); SQLBindCol(hstmt, 3, SQL_C_USHORT, &node, 0, NULL); sqlret = SQLFetch(hstmt); while ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { if (zone == cfg.MyAddr.zone) { wsprintfW(LogStr,L"Creating poll to %u:%u/%u", zone, net, node); AddLogEntry(LogStr); swprintf_s(tmpFileName, MAX_PATH, L"%s\\%04hX%04hX.CLO", cfg.BinkOutboundDir, net, node); hPktFile = CreateFileW(tmpFileName, GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); CloseHandle(hPktFile); // } sqlret = SQLFetch(hstmt); } SQLCloseCursor(hstmt); SQLFreeStmt(hstmt, SQL_UNBIND); } } } goto loop; threadexit: _InterlockedDecrement(&(cfg.ThreadCount)); SetEvent(cfg.hThreadEndEvent); return 0; }
bool CHttpDownloader::downLoadBreakpointFile() { DWORD dwBytesRead = 0; //char szReadBuf[DOWNLOADLEN]; char *szReadBuf = new char[DOWNLOADLEN]; if( !szReadBuf ) return false; ZeroMemory(szReadBuf, DOWNLOADLEN); DWORD dwBytesToRead = DOWNLOADLEN; wchar_t wcsNum[255]; DWORD dwRegType = 0, dwReturnSize = sizeof(wcsNum), dwFilePoint; UINT64 uI64Num = 0; bool bIsBreak = false; uI64Num = isBreakPointFile(m_strSaveFile.c_str()); dwFilePoint = (DWORD)(uI64Num); if( dwFilePoint > 0 )//续传文件 { bIsBreak = true; m_hSaveFile = CreateFile(m_strSaveFile.c_str(), MYWIRTEFILE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (m_hSaveFile == INVALID_HANDLE_VALUE)//断点文件不存在 { m_hSaveFile = CreateFile(m_strSaveFile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); } else { if(INVALID_SET_FILE_POINTER == SetFilePointer(m_hSaveFile,dwFilePoint,NULL,FILE_BEGIN) ) { CloseHandles(); delete []szReadBuf; return ERR_DISKERROR; } m_ui64TotalRead = dwFilePoint; } } else//重新下载 { m_hSaveFile = CreateFile(m_strSaveFile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); } if ( INVALID_HANDLE_VALUE == m_hSaveFile ) { CloseHandles(); delete []szReadBuf; return ERR_DISKERROR; } do { NEED_STOP; if (!::InternetReadFile(m_hInetFile, szReadBuf, dwBytesToRead, &dwBytesRead)) { CloseHandles(); if(m_repeatNum < REPEATNUM) { m_repeatNum ++; DWORD dwBegin = GetTickCount(); while( GetTickCount() - dwBegin < 1000 * m_repeatNum * 20) Sleep(20000); delete []szReadBuf; return this->TransferDataGet() == 0 ? false:true ; } else { delete []szReadBuf; return ERR_FILENOTFOUND; } } else if (dwBytesRead) { DWORD dwBytesWritten = 0; if (!WriteFile(m_hSaveFile, szReadBuf, dwBytesRead, &dwBytesWritten, NULL)) { //文件写入错误,反馈 CRecordProgram::GetInstance()->FeedbackError(MY_ERROR_PRO_NAME, MY_EEEOR_ID_FILER, MY_ERROR_DESCRIPT_FILER); CloseHandles(); delete []szReadBuf; return ERR_DISKERROR; } m_ui64TotalRead += dwBytesRead; if (m_pUpdateMgr) m_pUpdateMgr->SetProgressVal(m_ui64FileSize, m_ui64TotalRead); } } while (dwBytesRead); CloseHandles(); if( !MoveFileExW(m_strSaveFile.c_str(), m_wcsOriginalFileName.c_str() , MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED ) ) { CDownloadOperation don; don.deleteAllUpdataFile(); } m_wcsOriginalFileName = L"error"; delete []szReadBuf; return ERR_SUCCESS; }
BOOL WipeFileW(wchar_t *filename) { DWORD Error=0,OldAttr,needed; void *SD=NULL; int correct_SD=FALSE; wchar_t dir[2*MAX_PATH],tmpname[MAX_PATH],*fileptr=wcsrchr(filename,L'\\'); unsigned char *buffer=(unsigned char *)malloc(BUFF_SIZE); if(fileptr&&buffer) { OldAttr=GetFileAttributesW(filename); SetFileAttributesW(filename,OldAttr&(~FILE_ATTRIBUTE_READONLY)); if(!GetFileSecurityW(filename,DACL_SECURITY_INFORMATION,NULL,0,&needed)) if(GetLastError()==ERROR_INSUFFICIENT_BUFFER) { SD=malloc(needed); if(SD) if(GetFileSecurityW(filename,DACL_SECURITY_INFORMATION,SD,needed,&needed)) correct_SD=TRUE; } wcsncpy(dir,filename,fileptr-filename+1); dir[fileptr-filename+1]=0; if(GetTempFileNameW(dir,L"bc",0,tmpname)) { if(MoveFileExW(filename,tmpname,MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH)) { HANDLE f=CreateFileW(tmpname,FILE_GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_SEQUENTIAL_SCAN,NULL); if(f!=INVALID_HANDLE_VALUE) { BY_HANDLE_FILE_INFORMATION info; if(GetFileInformationByHandle(f,&info)) { unsigned long long size=(unsigned long long)info.nFileSizeLow+(unsigned long long)info.nFileSizeHigh*4294967296ULL; unsigned long long processed_size=0; while(size) { unsigned long outsize=(unsigned long)((size>=BUFF_SIZE)?BUFF_SIZE:size),transferred; WriteFile(f,buffer,outsize,&transferred,NULL); size-=outsize; processed_size+=outsize; if(UpdatePosInfo(0ULL,processed_size)) break; } } if((SetFilePointer(f,0,NULL,FILE_BEGIN)==INVALID_SET_FILE_POINTER)||(!SetEndOfFile(f))) Error=GetLastError(); CloseHandle(f); } if(Error) MoveFileExW(tmpname,filename,MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH); else if(!DeleteFileW(tmpname)) Error=GetLastError(); } else { Error=GetLastError(); DeleteFileW(tmpname); } } else Error=GetLastError(); if(Error) { SetFileAttributesW(filename,OldAttr); if(correct_SD) SetFileSecurityW(filename,DACL_SECURITY_INFORMATION,SD); } } free(SD); free(buffer); if(Error) { SetLastError(Error); return FALSE; } return TRUE; }
bool VT::move_file(const std::wstring& filename, const std::wstring& newFile) { return (MoveFileExW(filename.c_str(), newFile.c_str(), MOVEFILE_REPLACE_EXISTING) == TRUE); }