📄 intrface.cpp
字号:
// I hate to do this... Take a giant step out of here. longjmp(dll_error_return, PK_ABORTED); }}//******************************************************************************void SetCurrentFile(Uz_Globs *pG) { // Reset all our counters as we about to process a new file. g_pExtractInfo->dwFileOffset = (DWORD)pG->pInfo->offset; g_pExtractInfo->dwFile++; g_pExtractInfo->dwBytesWrittenThisFile = 0; g_pExtractInfo->dwBytesWrittenPreviousFiles += g_pExtractInfo->dwBytesTotalThisFile; g_pExtractInfo->dwBytesTotalThisFile = pG->ucsize; g_pExtractInfo->szFile = pG->filename; g_pExtractInfo->fNewLineOfText = TRUE; // Pass control to our GUI thread to do a full update our progress dialog. SendMessage(g_hWndMain, WM_PRIVATE, MSG_UPDATE_PROGRESS_COMPLETE, (LPARAM)g_pExtractInfo); // Check our abort flag. CheckForAbort(pG);}//******************************************************************************//***** Callbacks from Info-ZIP code.//******************************************************************************int UzpMessagePrnt2(zvoid *pG, uch *buffer, ulg size, int flag) { // Some ZIP files cause us to get called during DoListFiles(). We only handle // messages while processing DoExtractFiles(). if (!g_pExtractInfo) { if (g_hWndEdit) { SendMessage(g_hWndMain, WM_PRIVATE, MSG_ADD_TEXT_TO_EDIT, (LPARAM)buffer); } else { DebugOut(TEXT("Unhandled call to UzpMessagePrnt2(\"%S\")"), buffer); } return 0; } // When extracting, mapname() will get called for every file which in turn // will call SetCurrentFile(). For testing though, mapname() never gets // called so we need to be on the lookout for a new file. if (g_pExtractInfo->dwFileOffset != (DWORD)((Uz_Globs*)pG)->pInfo->offset) { SetCurrentFile((Uz_Globs*)pG); } // Make sure this message was inteded for us to display. if (!MSG_NO_WGUI(flag) && !MSG_NO_WDLL(flag)) { // Insert a leading newline if requested to do so. if (MSG_LNEWLN(flag) && !g_pExtractInfo->fNewLineOfText) { SendMessage(g_hWndMain, WM_PRIVATE, MSG_ADD_TEXT_TO_EDIT, (LPARAM)"\n"); g_pExtractInfo->fNewLineOfText = TRUE; } // Since we use a proportional font, we need to do a little cleanup of the // text we are passed since it assumes a fixed font and adds padding to try // to line things up. We remove leading whitespace on any new line of text. if (g_pExtractInfo->fNewLineOfText) { while (*buffer == ' ') { buffer++; } } // We always remove trailing whitespace. LPSTR psz = (LPSTR)buffer + strlen((LPSTR)buffer) - 1; while ((psz >= (LPSTR)buffer) && (*psz == ' ')) { *(psz--) = '\0'; } // Determine if the next line of text will be a new line of text. g_pExtractInfo->fNewLineOfText = ((*psz == '\r') || (*psz == '\n')); // Change all forward slashes to back slashes in the buffer ForwardSlashesToBackSlashesA((LPSTR)buffer); // Add the cleaned-up text to our extraction log edit control. SendMessage(g_hWndMain, WM_PRIVATE, MSG_ADD_TEXT_TO_EDIT, (LPARAM)buffer); // Append a trailing newline if requested to do so. if (MSG_TNEWLN(flag) || MSG_MNEWLN(flag) && !g_pExtractInfo->fNewLineOfText) { SendMessage(g_hWndMain, WM_PRIVATE, MSG_ADD_TEXT_TO_EDIT, (LPARAM)"\n"); g_pExtractInfo->fNewLineOfText = TRUE; } } return 0;}//******************************************************************************int UzpInput2(zvoid *pG, uch *buffer, int *size, int flag) { DebugOut(TEXT("WARNING: UzpInput2(...) called")); return 0;}//******************************************************************************void UzpMorePause(zvoid *pG, const char *szPrompt, int flag) { DebugOut(TEXT("WARNING: UzpMorePause(...) called"));}//******************************************************************************int UzpPassword(zvoid *pG, int *pcRetry, char *szPassword, int nSize, const char *szZipFile, const char *szFile){ // Return Values: // IZ_PW_ENTERED got some PWD string, use/try it // IZ_PW_CANCEL no password available (for this entry) // IZ_PW_CANCELALL no password, skip any further PWD request // IZ_PW_ERROR failure (no mem, no tty, ...)#if CRYPT // Build the data structure for our dialog. DECRYPT_INFO di; di.retry = *pcRetry; di.szPassword = szPassword; di.nSize = nSize; di.szFile = szFile; // Clear the password to be safe. *di.szPassword = '\0'; // On our first call for a file, *pcRetry == 0. If we would like to allow // for retries, then we set the value of *pcRetry to the number of retries we // are willing to allow. We will be recalled as neccessary, each time with // *pcRetry being decremented once. 1 is the last retry we will get. *pcRetry = (*pcRetry == 0) ? MAX_PASSWORD_RETRIES : (*pcRetry - 1); // Pass control to our GUI thread which will prompt the user for a password. return SendMessage(g_hWndMain, WM_PRIVATE, MSG_PROMPT_FOR_PASSWORD, (LPARAM)&di);#else return -2;#endif}//******************************************************************************int WINAPI UzpReplace(char *szFile) { // Pass control to our GUI thread which will prompt the user to overwrite. return SendMessage(g_hWndMain, WM_PRIVATE, MSG_PROMPT_TO_REPLACE, (LPARAM)szFile);}//******************************************************************************void WINAPI UzpSound(void) { // Do nothing.}//******************************************************************************// Called from LIST.Cvoid WINAPI SendAppMsg(ulg dwSize, ulg dwCompressedSize, int ratio, int month, int day, int year, int hour, int minute, int uppercase, char *szPath, char *szMethod, ulg dwCRC){ // If we are out of memory, then just bail since we will only make things worse. if (g_fOutOfMemory) { return; } // We get our Globals structure and then retrieve the real file name. GETGLOBALS() szPath = pG->filename; // Allocate a FILE_NODE large enough to hold this file. int length = strlen(szPath) + strlen(szMethod); g_pFileLast = (FILE_NODE*)new BYTE[sizeof(FILE_NODE) + (sizeof(TCHAR) * length)]; // Bail out if we failed to allocate the node. if (!g_pFileLast) { DebugOut(TEXT("Failed to create a FILE_NODE for \"%S\"."), szPath); g_fOutOfMemory = TRUE; return; } // Fill in our node. g_pFileLast->dwSize = dwSize; g_pFileLast->dwCompressedSize = dwCompressedSize; g_pFileLast->dwCRC = dwCRC; g_pFileLast->szComment = NULL; g_pFileLast->szType = NULL; // Fix the year value to contain the real year. year += 1900; // Year: 0 - 4095 (12) 1111 1111 1111 0000 0000 0000 0000 0000 (0xFFF00000) // Month: 1 - 12 ( 4) 0000 0000 0000 1111 0000 0000 0000 0000 (0x000F0000) // Day: 1 - 31 ( 5) 0000 0000 0000 0000 1111 1000 0000 0000 (0x0000F800) // Hour: 0 - 23 ( 5) 0000 0000 0000 0000 0000 0111 1100 0000 (0x000007C0) // Minute: 0 - 59 ( 6) 0000 0000 0000 0000 0000 0000 0011 1111 (0x0000003F) // Do some bit shifting to make the date and time fit in a DWORD. g_pFileLast->dwModified = (((DWORD)(year & 0x0FFF) << 20) | ((DWORD)(month & 0x000F) << 16) | ((DWORD)(day & 0x001F) << 11) | ((DWORD)(hour & 0x001F) << 6) | ((DWORD)(minute & 0x003F))); // We need to get our globals structure to determine our attributes and // encryption information. g_pFileLast->dwAttributes = (pG->crec.external_file_attributes & 0xFF); if (pG->crec.general_purpose_bit_flag & 1) { g_pFileLast->dwAttributes |= FILE_ATTRIBUTE_ENCRYPTED; } // Store the path and method in our string buffer. strcpy(g_pFileLast->szPathAndMethod, szPath); strcpy(g_pFileLast->szPathAndMethod + strlen(szPath) + 1, szMethod); // Pass the file object to our windows code to have it added to our list. AddFileToListView(g_pFileLast);}//******************************************************************************int win_fprintf(FILE *file, unsigned int dwCount, char far *buffer) { // win_fprintf() is used within Info-ZIP to write to a file as well as log // information. If the "file" is a real file handle (not stdout or stderr), // then we write the data to the file and return. if ((file != stdout) && (file != stderr)) { DWORD dwBytesWriten = 0;#ifdef _WIN32_WCE // On WinCE all FILEs are really HANDLEs. See WINCE.CPP for more info. WriteFile((HANDLE)file, buffer, dwCount, &dwBytesWriten, NULL);#else dwBytesWriten = fwrite(buffer, 1, dwCount, file);#endif // Update our bytes written count. g_pExtractInfo->dwBytesWrittenThisFile += dwBytesWriten; // Pass control to our GUI thread to do a partial update our progress dialog. SendMessage(g_hWndMain, WM_PRIVATE, MSG_UPDATE_PROGRESS_PARTIAL, (LPARAM)g_pExtractInfo); // Check our abort flag. GETGLOBALS(); CheckForAbort(pG); return dwBytesWriten; } // Check to see if we are expecting a extraction progress string if (g_pExtractInfo) { // Most of our progress strings come to our UzpMessagePrnt2() callback, // but we occasionally get one here. We will just forward it to // UzpMessagePrnt2() as if it never came here. To do this, we need to // get a pointer to our Globals struct. Calling GETGLOBALS() sort of // breaks us from be REENTRANT, but we don't support that anyway. GETGLOBALS(); UzpMessagePrnt2(pG, (uch*)buffer, dwCount, 0); return dwCount; } // Check to see if we are expecting a zip file comment string. if (g_hWndEdit) { // Change all forward slashes to back slashes in the buffer ForwardSlashesToBackSlashesA((LPSTR)buffer); SendMessage(g_hWndMain, WM_PRIVATE, MSG_ADD_TEXT_TO_EDIT, (LPARAM)buffer); return dwCount; } // Check to see if we are expecting a compressed file comment string. if (g_pFileLast) { // Calcalute the size of the buffer we will need to store this comment. // We are going to convert all ASC values 0 - 31 (excpet tab, new line, // and CR) to ^char. int size = 1; for (char *p2, *p1 = buffer; *p1; p1++) { size += ((*p1 >= 32) || (*p1 == '\t') || (*p1 == '\r') || (*p1 == '\n')) ? 1 : 2; } // Allocate a comment buffer and assign it to the last file node we saw. if (g_pFileLast->szComment = new CHAR[size]) { // Copy while formatting. for (p1 = buffer, p2 = (char*)g_pFileLast->szComment; *p1; p1++) { if ((*p1 >= 32) || (*p1 == '\t') || (*p1 == '\r') || (*p1 == '\n')) { *(p2++) = *p1; } else { *(p2++) = '^'; *(p2++) = 64 + *p1; } } *p2 = '\0'; } // Update the attributes of the file node to incldue the comment attribute. g_pFileLast->dwAttributes |= FILE_ATTRIBUTE_COMMENT; // Clear the file node so we don't try to add another bogus comment to it. g_pFileLast = NULL; return dwCount; } if (dwCount >= _MAX_PATH) { buffer[_MAX_PATH] = '\0'; } DebugOut(TEXT("Unhandled call to win_fprintf(\"%S\")"), buffer); return dwCount;}//******************************************************************************//***** Functions that Info-ZIP expects the port to write and export.//***** Some of this code was stolen from the WIN32 port and highly modified.//******************************************************************************int mapattr(Uz_Globs *pG) { // Check to see if we are extracting this file for viewing. Currently, we do // this by checking the szMappedPath member of our extract info stucture // since we know OnActionView() is the only one who sets this member. if (g_pExtractInfo && g_pExtractInfo->szMappedPath) { // If we are extracting for view only, then we ignore the file's real // attributes and force the file to create as read-only. We make the file // read-only to help prevent the user from making changes to the temporary // file and then trying to save the changes back to a file that we will // eventually delete. pG->pInfo->file_attr = FILE_ATTRIBUTE_READONLY; } else { // Store the attribute exactly as it appears for normal extraction/test. pG->pInfo->file_attr = (unsigned)pG->crec.external_file_attributes & 0xff; } return PK_OK;}//******************************************************************************void utimeToFileTime(time_t ut, FILETIME *pft, BOOL fOldFileSystem) { // time_t is a 32-bit value for the seconds since January 1, 1970 // FILETIME is a 64-bit value for the number of 100-nanosecond intervals since // January 1, 1601 // DWORDLONG is a 64-bit int that we can use to perform large math operations. // time_t has minimum of 1/1/1970. Many file systems, such as FAT, have a // minimum date of 1/1/1980. If extracting to one of those file systems and // out time_t is less than 1980, then we make it 1/1/1980. // (365 days/yr * 10 yrs + 3 leap yr days) * (60 secs * 60 mins * 24 hrs). if (fOldFileSystem && (ut < 0x12CFF780)) { ut = 0x12CFF780; } // Compute the FILETIME for the given time_t. DWORDLONG dwl = ((DWORDLONG)116444736000000000 + ((DWORDLONG)ut * (DWORDLONG)10000000)); // Store the return value. *pft = *(FILETIME*)&dwl; // Now for the next fix for old file systems. If we are in Daylight Savings // Time (DST) and the file is not in DST, then we need subtract off the DST // bias from the filetime. This is due to a bug in Windows (NT, CE, and 95) // that causes the DST bias to be added to all file times when the system // is in DST, even if the file is not in DST. This only effects old file // systems since they store local times instead of UTC times. Newer file // systems like NTFS and CEFS store UTC times. if (fOldFileSystem) { // We use the CRT's localtime() and Win32's FileTimeToLocalTime() // functions to compute the DST bias. This works because localtime() // correctly adds the DST bias only if the file time is in DST. // FileTimeToLocalTime() always adds the DST bias to the time. // Therefore, if the functions return different results, we know we // are dealing with a non-DST file during a system DST. FILETIME ftCRT, ftWin32; // Get the CRT result - result is a "tm" struct.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -