📄 intrface.cpp
字号:
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 (chCrypt == 'E') { g_pFileLast->dwAttributes |= ZFILE_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(zvoid *pG, 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 dwBytesWritten = 0;#if (defined(_WIN32_WCE) && (_WIN32_WCE < 211)) // On WinCE all FILEs are really HANDLEs. See WINCE.CPP for more info. WriteFile((HANDLE)file, buffer, dwCount, &dwBytesWritten, NULL);#else dwBytesWritten = fwrite(buffer, 1, dwCount, file);#endif // Update our bytes written count. g_pExtractInfo->dwBytesWrittenThisFile += dwBytesWritten; // 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); return dwBytesWritten; } // 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. 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 (except tab, new line, // and CR) to ^char. int size = 1; for (char *p2, *p1 = buffer; *p1; INCSTR(p1)) { size += ((*p1 >= 32) || (*p1 == '\t') || (*p1 == '\r') || (*p1 == '\n')) ? CLEN(p1) : 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; INCSTR(p1)) { if ((*p1 >= 32) || (*p1 == '\t') || (*p1 == '\r') || (*p1 == '\n')) { memcpy(p2, p1, CLEN(p1)); p2 += CLEN(p1); } else { *(p2++) = '^'; *(p2++) = 64 + *p1; } } *p2 = '\0'; } // Update the attributes of the file node to include the comment attribute. g_pFileLast->dwAttributes |= ZFILE_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'; }#ifdef UNICODE DebugOut(TEXT("Unhandled call to win_fprintf(\"%S\")"), buffer);#else DebugOut(TEXT("Unhandled call to win_fprintf(\"%S\")"), buffer);#endif return dwCount;}//******************************************************************************void WINAPI Wiz_NoPrinting(int f) { // Do nothing.}#endif // POCKET_UNZIP//******************************************************************************//***** Functions that Info-ZIP expects the port to write and export.//***** Some of this code was stolen from the WIN32 port and highly modified.//******************************************************************************#ifdef NTSD_EAS#ifndef SFX//******************************************************************************// Called from EXTRACT.Cint test_NTSD(__GPRO__ uch *eb, unsigned eb_size) { // This function is called when an NT security descriptor is found in the // extra field. We have nothing to do, so we just return success. return PK_OK;}#endif /* !SFX */#endif /* NTSD_EAS */static 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 unsigned 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; }#ifndef NO_W32TIMES_IZFIX // 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)#endif { // We use the CRT's localtime() and Win32's LocalTimeToFileTime() // functions to compute a FILETIME value that always shows the correct // local time in Windows' file listings. 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 lftCRT; // Get the CRT result - result is a "tm" struct. struct tm *ptmCRT = localtime(&ut); // Check if localtime() returned something useful; continue with the // "NewFileSystem" code in case of an error. This failsafe method // should give an "almost" correct filetime result. if (ptmCRT != (struct tm *)NULL) { // Convert the "tm" struct to a FILETIME. SYSTEMTIME stCRT; ZeroMemory(&stCRT, sizeof(stCRT)); if (fOldFileSystem && (ptmCRT->tm_year < 80)) { stCRT.wYear = 1980; stCRT.wMonth = 1; stCRT.wDay = 1; stCRT.wHour = 0; stCRT.wMinute = 0; stCRT.wSecond = 0; } else { stCRT.wYear = ptmCRT->tm_year + 1900; stCRT.wMonth = ptmCRT->tm_mon + 1; stCRT.wDay = ptmCRT->tm_mday; stCRT.wHour = ptmCRT->tm_hour; stCRT.wMinute = ptmCRT->tm_min; stCRT.wSecond = ptmCRT->tm_sec; } SystemTimeToFileTime(&stCRT, &lftCRT); LocalFileTimeToFileTime(&lftCRT, pft); // we are finished! return; } } // For "Modern" file system that stores timestamps in UTC (or as second // chance in case of localtime() errors) the conversion of time_t into // 64-bit FILETIME is a simple arithmetic rescaling calculation. // Compute the FILETIME for the given time_t. DWORDLONG dwl = ((DWORDLONG)116444736000000000 + ((DWORDLONG)ut * (DWORDLONG)10000000)); // Store the return value. *pft = *(FILETIME*)&dwl;}//******************************************************************************static int GetFileTimes(__GPRO__ FILETIME *pftCreated, FILETIME *pftAccessed, FILETIME *pftModified){ // We need to check to see if this file system is limited. This includes // FAT, VFAT, and HPFS. It does not include NTFS and CEFS. The limited // file systems can not support dates < 1980 and they store file local times // for files as opposed to UTC times. BOOL fOldFileSystem = IsOldFileSystem(G.filename);#ifdef USE_EF_UT_TIME // Always true for WinCE build#ifdef IZ_CHECK_TZ if (G.extra_field && G.tz_is_valid) {#else if (G.extra_field) {#endif // Structure for Unix style actime, modtime, creatime iztimes z_utime; // Get any date/time we can. This can return 0 to 3 unix time fields. unsigned eb_izux_flg = ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime, &z_utime, NULL); // We require at least a modified time. if (eb_izux_flg & EB_UT_FL_MTIME) { // We know we have a modified time, so get it first. utimeToFileTime(z_utime.mtime, pftModified, fOldFileSystem); // Get the accessed time if we have one. if (eb_izux_flg & EB_UT_FL_ATIME) { utimeToFileTime(z_utime.atime, pftAccessed, fOldFileSystem); } // Get the created time if we have one. if (eb_izux_flg & EB_UT_FL_CTIME) { utimeToFileTime(z_utime.ctime, pftCreated, fOldFileSystem); } // Return our flags. return (int)eb_izux_flg; } }#endif // USE_EF_UT_TIME // If all else fails, we can resort to using the DOS date and time data. time_t ux_modtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime); utimeToFileTime(ux_modtime, pftModified, fOldFileSystem); *pftAccessed = *pftModified; return (EB_UT_FL_MTIME | EB_UT_FL_ATIME);}//******************************************************************************//***** Functions to correct time stamp bugs on old file systems.//******************************************************************************//******************************************************************************// Borrowed/Modified from win32.cstatic BOOL IsOldFileSystem(char *szPath) {#ifdef _WIN32_WCE char szRoot[10]; // Get the first nine characters of the path. strncpy(szRoot, szPath, 9); szRoot[9] = '\0'; // Convert to uppercase to help with compare. _strupr(szRoot); // PC Cards are mounted off the root in a directory called "\PC Cards". // PC Cards are FAT, no CEOS. We need to check if the file is being // extracted to the PC card. return !strcmp(szRoot, "\\PC CARD\\");#else char szRoot[_MAX_PATH] = "\0\0\0", szFS[64]; // Check to see if our path contains a drive letter. if (isalpha(szPath[0]) && (szPath[1] == ':') && (szPath[2] == '\\')) { // If so, then just copy the drive letter, colon, and wack to our root path. strncpy(szRoot, szPath, 3); } else { // Expand the path so we can get a drive letter. GetFullPathNameA(szPath, sizeof(szRoot), szRoot, NULL); // Make sure we actually got a drive letter back in our root path buffer.. if (!isalpha(szRoot[0]) || (szRoot[1] != ':') || (szRoot[2] != '\\')) { // When in doubt, return TRUE. return TRUE; } } // NULL terminate after the wack to ensure we have just the root path. szRoot[3] = '\0'; // Get the file system type string. GetVolumeInformationA(szRoot, NULL, 0, NULL, NULL, NULL, szFS, sizeof(szFS)); // Ensure that the file system type string is uppercase. _strupr(szFS); // Return true for (V)FAT and (OS/2) HPFS format. return !strncmp(szFS, "FAT", 3) || !strncmp(szFS, "VFAT", 4) || !strncmp(szFS, "HPFS", 4);#endif // _WIN32_WCE}//******************************************************************************int SetFileSize(FILE *file, ulg filesize){#if (defined(_WIN32_WCE) || defined(__RSXNT__)) // For native Windows CE, it is not known whether the API supports // presetting a file's size. // RSXNT environment lacks a translation function from C file pointer // to Win32-API file handle. // So, simply do nothing. return 0;#else /* !(_WIN32_WCE || __RSXNT__) */ /* not yet verified, if that really creates an unfragmented file rommel@ars.de */ HANDLE os_fh; /* Win9x supports FAT file system, only; presetting file size does not help to prevent fragmentation. */ if ((long)GetVersion() < 0) return 0; /* Win32-API calls require access to the Win32 file handle. The interface function used to retrieve the Win32 handle for a file opened by the C rtl is non-standard and may not be available for every Win32 compiler environment. (see also win32/win32.c of the Zip distribution) */ os_fh = (HANDLE)_get_osfhandle(fileno(file)); /* move file pointer behind the last byte of the expected file size */ if (SetFilePointer(os_fh, filesize, 0, FILE_BEGIN) == 0xFFFFFFFF) return -1; /* extend/truncate file to the current position */ if (SetEndOfFile(os_fh) == 0) return -1; /* move file position pointer back to the start of the file! */ return (SetFilePointer(os_fh, 0, 0, FILE_BEGIN) == 0xFFFFFFFF) ? -1 : 0;#endif /* ?(_WIN32_WCE || __RSXNT__) */} /* end function SetFileSize() *///******************************************************************************void close_outfile(__GPRO){ HANDLE hFile; // Get the 3 time stamps for the file. FILETIME ftCreated, ftAccessed, ftModified; int timeFlags = GetFileTimes(__G__ &ftCreated, &ftAccessed, &ftModified); TCHAR szFile[_MAX_PATH]; MBSTOTSTR(szFile, G.filename, countof(szFile));#if (defined(_WIN32_WCE) && (_WIN32_WCE < 211)) // Cast the outfile to a HANDLE (since that is really what it is), and // flush the file. We need to flush, because any unsaved data that is // written to the file during CloseHandle() will step on the work done // by SetFileTime(). hFile = (HANDLE)G.outfile; FlushFileBuffers(hFile);#else // Close the file and then re-open it using the Win32 CreateFile() call. // SetFileTime() requires a Win32 file HANDLE created with GENERIC_WRITE // access. fclose(G.outfile); hFile = CreateFile(szFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);#endif // Set the file's date and time. if (hFile != INVALID_HANDLE_VALUE) { // Make sure we retrieved some valid time stamp(s) if (timeFlags) { // Set the various date and time fields. if (!SetFileTime(hFile, (timeFlags & EB_UT_FL_CTIME) ? &ftCreated : NULL,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -