/***************************************************************************** static DWORD CreateChecksumFiles_OnePerFile(CONST UINT uiMode, list<FILEINFO*> *finalList) uiMode : (IN) create MD5/SFV/SHA1 files finalList : (IN) pointer to list of fileinfo pointers on which the action is to be performed Return Value: returns NOERROR or GetLastError() Notes: - handles the situation if the user want one entry per sfv/md5 file *****************************************************************************/ static DWORD CreateChecksumFiles_OnePerFile(CONST UINT uiMode, list<FILEINFO*> *finalList) { FILEINFO * pFileinfo; DWORD dwResult; TCHAR szFileOut[MAX_PATH_EX]; HANDLE hFile; for(list<FILEINFO*>::iterator it=finalList->begin();it!=finalList->end();it++) { pFileinfo = (*it); if( pFileinfo->dwError == NO_ERROR ){ StringCchPrintf(szFileOut,MAX_PATH_EX,TEXT("%s.%s"), pFileinfo->szFilename, g_hash_ext[uiMode]); if(g_program_options.bNoHashFileOverride && FileExists(szFileOut)) { continue; } hFile = CreateFile(szFileOut, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, NULL); if(hFile == INVALID_HANDLE_VALUE) return GetLastError(); #ifdef UNICODE //we need a BOM if we are writing unicode if(!WriteCurrentBOM(hFile)) return GetLastError(); #endif if(uiMode == MODE_SFV && g_program_options.bWinsfvComp){ dwResult = WriteSfvHeader(hFile); if(dwResult != NOERROR){ CloseHandle(hFile); return dwResult; } } if(g_program_options.bIncludeFileComments) { dwResult = WriteFileComment(hFile, pFileinfo, (UINT)(GetFilenameWithoutPathPointer(pFileinfo->szFilenameShort) - pFileinfo->szFilename)); if(dwResult != NOERROR){ CloseHandle(hFile); return dwResult; } } dwResult = WriteHashLine(hFile, GetFilenameWithoutPathPointer(pFileinfo->szFilename), pFileinfo->hashInfo[uiMode].szResult, uiMode == MODE_SFV); CloseHandle(hFile); if(dwResult != NOERROR) return dwResult; } } return NOERROR; }
static BOOL GenerateFilename_OneFile(CONST HWND owner, CONST TCHAR *szDefault, UINT uiMode, TCHAR szFileOut[MAX_PATH_EX], BOOL askForFilename) { TCHAR szCurrentPath[MAX_PATH_EX] = TEXT(""); OPENFILENAME ofn; size_t strLen; StringCchLength(szDefault, MAX_PATH_EX, &strLen); if(strLen > 4) { // if < 4 no extended path - something went wrong // get rid of \\?\(UNC) if(strLen > 6 && !_tcsncmp(szDefault + 4, TEXT("UNC"), 3)) { szCurrentPath[0] = TEXT('\\'); StringCchCopy(szCurrentPath + 1, MAX_PATH_EX, szDefault + 7); strLen -= 6; } else { StringCchCopy(szCurrentPath, MAX_PATH_EX, szDefault + 4); strLen -= 4; } StringCchCopy(szFileOut, MAX_PATH_EX, szCurrentPath); szCurrentPath[strLen - 1] = TEXT('\0'); // get rid of last backslash for GetFilenameWithoutPathPointer StringCchCat(szFileOut, MAX_PATH_EX, GetFilenameWithoutPathPointer(szCurrentPath)); if(szCurrentPath[strLen - 2] == TEXT(':')) szFileOut[4] = TEXT('\0'); } else { StringCchCopy(szCurrentPath, MAX_PATH_EX, TEXT("C:\\")); StringCchCopy(szFileOut, MAX_PATH_EX, TEXT("C:\\default")); } TCHAR *hashExt = g_hash_ext[uiMode]; // manually add file extension, windows dialog does not do this if the name already // ends in a known extension StringCchCat(szFileOut, MAX_PATH_EX, TEXT(".")); StringCchCat(szFileOut, MAX_PATH_EX, hashExt); if(askForFilename) { TCHAR msgString[MAX_PATH_EX]; TCHAR filterString[MAX_PATH_EX]; StringCchPrintf(filterString,MAX_PATH_EX,TEXT(".%s files%c*.%s%cAll files%c*.*%c"),hashExt,TEXT('\0'),hashExt,TEXT('\0'),TEXT('\0'),TEXT('\0')); StringCchPrintf(msgString,MAX_PATH_EX,TEXT("Please choose a filename for the .%s file"),hashExt); ZeroMemory(& ofn, sizeof (OPENFILENAME)); ofn.lStructSize = sizeof (OPENFILENAME); ofn.hwndOwner = owner; ofn.lpstrFilter = filterString; ofn.lpstrFile = szFileOut; ofn.nMaxFile = MAX_PATH_EX; ofn.lpstrInitialDir = szCurrentPath; ofn.lpstrTitle = msgString; ofn.Flags = OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_NOCHANGEDIR; ofn.lpstrDefExt = hashExt; if(! GetSaveFileName(& ofn) ){ return FALSE; } } return TRUE; }
/***************************************************************************** BOOL GetCrcFromFilename(TCHAR szFilename[MAX_PATH], DWORD * pdwFoundCrc) szFilename : (IN) string; assumed to be the szFilenameShort member of the FILEINFO struct pdwFoundCrc : (OUT) return value is TRUE this parameter is set to the found CRC32 as a DWORD Return Value: returns TRUE if a CRC was found in the filename. Otherwise FALSE Notes: - walks through a filename from the rear to the front. - if a ']' or ')' is found we check if 9 chars before is an '[' or '(' and if there are 8 legal Hex characters in between (via IsLegalHexSymbol) *****************************************************************************/ BOOL GetCrcFromFilename(CONST TCHAR szFilename[MAX_PATH], DWORD * pdwFoundCrc) { size_t StringSize; INT iIndex; BOOL bFound; TCHAR szCrc[9]; TCHAR szFileWithoutPath[MAX_PATH]; StringCchCopy(szFileWithoutPath, MAX_PATH, GetFilenameWithoutPathPointer(szFilename)); if(FAILED(StringCchLength(szFileWithoutPath, MAX_PATH, &StringSize))) return FALSE; if(StringSize == 0) return FALSE; iIndex = (int)StringSize; bFound = FALSE; do{ --iIndex; if((szFileWithoutPath[iIndex] == TEXT(']')) || (szFileWithoutPath[iIndex] == TEXT(')')) ) { if ((iIndex - 9) < 0) break; else{ bFound = TRUE; if (! ((szFileWithoutPath[iIndex-9] == TEXT('[')) || (szFileWithoutPath[iIndex-9] == TEXT('(')) ) ) bFound = FALSE; for(int i=1; i <= 8; ++i) if(! IsLegalHexSymbol(szFileWithoutPath[iIndex-i])) bFound = FALSE; if(bFound) iIndex -= 8; } } } while((iIndex > 0) && (!bFound)); if(!bFound) return FALSE; StringCchCopyN(szCrc, 9, szFileWithoutPath + iIndex, 8); (*pdwFoundCrc) = HexToDword(szCrc, 8); return TRUE; }
/***************************************************************************** static DWORD CreateChecksumFiles_OnePerDir(CONST UINT uiMode,CONST TCHAR szChkSumFilename[MAX_PATH_EX], list<FILEINFO*> *finalList) uiMode : (IN) create MD5 or SFV files szChkSumFilename: (IN) filename without path finalList : (IN) pointer to list of fileinfo pointers on which the action is to be performed Return Value: returns NOERROR or GetLastError() Notes: - handles the situation if the user want one sfv/md5 file per directory. In every directory a file with the name szChkSumFilename is created *****************************************************************************/ static DWORD CreateChecksumFiles_OnePerDir(CONST UINT uiMode,CONST TCHAR szChkSumFilename[MAX_PATH_EX], list<FILEINFO*> *finalList) { DWORD dwResult; TCHAR szCurrentDir[MAX_PATH_EX]; TCHAR szCurChecksumFilename[MAX_PATH_EX]; TCHAR szPreviousDir[MAX_PATH_EX] = TEXT("?:><"); // some symbols that are not allowed in filenames to force // the checksum file creation in the for loop HANDLE hFile = NULL; for(list<FILEINFO*>::iterator it=finalList->begin();it!=finalList->end();it++) { if( (*it)->dwError == NO_ERROR ){ StringCchCopy(szCurrentDir, MAX_PATH_EX, (*it)->szFilename); ReduceToPath(szCurrentDir); if(lstrcmpi(szPreviousDir, szCurrentDir) != 0){ if(hFile) { CloseHandle(hFile); hFile = NULL; } StringCchCopy(szPreviousDir, MAX_PATH_EX, szCurrentDir); StringCchPrintf(szCurChecksumFilename, MAX_PATH_EX, TEXT("%s%s"), szCurrentDir, szChkSumFilename); if(g_program_options.bNoHashFileOverride && FileExists(szCurChecksumFilename)) { continue; } hFile = CreateFile(szCurChecksumFilename, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, NULL); if(hFile == INVALID_HANDLE_VALUE){ return GetLastError(); } #ifdef UNICODE // we need a BOM if we are writing unicode if(!WriteCurrentBOM(hFile)) return GetLastError(); #endif if( (uiMode == MODE_SFV) && g_program_options.bWinsfvComp){ dwResult = WriteSfvHeader(hFile); if(dwResult != NOERROR){ CloseHandle(hFile); return dwResult; } } if(g_program_options.bIncludeFileComments) { list<FILEINFO*>::iterator commentIt = it; do { if((*commentIt)->dwError == NO_ERROR) { WriteFileComment(hFile, (*commentIt), (UINT)(GetFilenameWithoutPathPointer((*commentIt)->szFilenameShort) - (*commentIt)->szFilename)); } commentIt++; if(commentIt == finalList->end()) break; StringCchCopy(szCurrentDir, MAX_PATH_EX, (*commentIt)->szFilename); ReduceToPath(szCurrentDir); } while(lstrcmpi(szPreviousDir, szCurrentDir) == 0); } } if(hFile) { dwResult = WriteHashLine(hFile, GetFilenameWithoutPathPointer((*it)->szFilenameShort), (*it)->hashInfo[uiMode].szResult, uiMode == MODE_SFV); if(dwResult != NOERROR){ CloseHandle(hFile); return dwResult; } } } } CloseHandle(hFile); return NOERROR; }