📄 intrface.cpp
字号:
(timeFlags & EB_UT_FL_ATIME) ? &ftAccessed : NULL, (timeFlags & EB_UT_FL_MTIME) ? &ftModified : NULL)) { DebugOut(TEXT("SetFileTime() failed [%u]"), GetLastError()); } } else { DebugOut(TEXT("GetFileTimes() failed")); } // Close out file. CloseHandle(hFile); } else { DebugOut(TEXT("CreateFile() failed [%u]"), GetLastError()); } // If the file was successfully written, then set the attributes.#ifdef POCKET_UNZIP if (!G.disk_full && !g_pExtractInfo->fAbort) {#else if (!G.disk_full) {#endif if (!SetFileAttributes(szFile, G.pInfo->file_attr & 0x7F)) { DebugOut(TEXT("SetFileAttributes() failed [%u]"), GetLastError()); } } // Clear outfile so we know it is closed. G.outfile = 0; return;}//******************************************************************************// Called by PROCESS.Cchar* do_wild(__GPRO__ ZCONST char *wildspec){ // This is a very slimmed down version of do_wild() taken from WIN32.C. // Since we don't support wildcards, we basically just return the wildspec // passed in as the filename.#ifndef POCKET_UNZIP // Delete allocated storage for the match name if (G.matchname != NULL) { delete G.matchname; G.matchname = NULL; }#endif // First call - must initialize everything. if (!G.notfirstcall) { G.notfirstcall = TRUE;#ifdef POCKET_UNZIP return strcpy(G.matchname, wildspec);#else // allocate some storage for the match name G.matchname = new char[strlen(wildspec) + 1]; if (G.matchname != NULL) return strcpy(G.matchname, wildspec);#endif } // Last time through - reset for new wildspec. G.notfirstcall = FALSE; return (char *)NULL;}//******************************************************************************// Called from EXTRACT.Cint mapattr(__GPRO){#ifdef POCKET_UNZIP // 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. G.pInfo->file_attr = FILE_ATTRIBUTE_READONLY; } else#endif { /* set archive bit for file entries (file is not backed up): */ G.pInfo->file_attr = ((unsigned)G.crec.external_file_attributes | (G.crec.external_file_attributes & FILE_ATTRIBUTE_DIRECTORY ? 0 : FILE_ATTRIBUTE_ARCHIVE)) & 0xff; } return 0;} /* end function mapattr() *///******************************************************************************// Called from EXTRACT.C//// returns:// MPN_OK - no problem detected// MPN_INF_TRUNC - (on APPEND_NAME) truncated filename// MPN_INF_SKIP - path doesn't exist, not allowed to create// MPN_ERR_SKIP - path doesn't exist, tried to create and failed; or path// exists and is not a directory, but is supposed to be// MPN_ERR_TOOLONG - path is too long// MPN_NOMEM - can't allocate memory for filename buffers//// MPN_VOL_LABEL - Path was a volume label, skip it.// MPN_CREATED_DIR - Created a directory.//int mapname(__GPRO__ int renamed){ int error = MPN_OK; CHAR szBuffer[countof(G.filename)] = ""; CHAR *pIn = NULL, *pOut, *pLastSemi = NULL; CHAR *pPathComp, workch; BOOL killed_ddot = FALSE, renamed_fullpath = FALSE, created_dir = FALSE;#ifdef POCKET_UNZIP // mapname() is a great place to reset all our status counters for the next // file to be processed since it is called for every zip file member before // any work is done with that member. SetCurrentFile(__G);#endif // If Volume Label, skip the "extraction" quietly if (G.pInfo->vollabel) { return MPN_VOL_LABEL; }#ifndef POCKET_UNZIP // The GUI interface does not support renaming... if (renamed) { pIn = G.filename; // point to beginning of renamed name... if (*pIn) do { if (*pIn == '\\') // convert backslashes to forward *pIn = '/'; } while (*PREINCSTR(pIn)); pIn = G.filename; // use temporary rootpath if user gave full pathname if (G.filename[0] == '/') { renamed_fullpath = TRUE; szBuffer[0] = '\\'; // copy the '/' and terminate szBuffer[1] = '\0'; ++pIn; } else if (isalpha((uch)G.filename[0]) && G.filename[1] == ':') { renamed_fullpath = TRUE; pOut = szBuffer; *pOut++ = *pIn++; // copy the "d:" (+ '/', possibly) *pOut++ = *pIn++; if (*pIn == '/') { *pOut++ = '\\'; pIn++; // otherwise add "./"? } *pOut = '\0'; } }#endif // Initialize file path buffer with our "extract to" path. if (!renamed_fullpath) {#ifdef POCKET_UNZIP strcpy(szBuffer, g_szExtractToDirectory);#else strcpy(szBuffer, G.rootpath);#endif pOut = szBuffer + strlen(szBuffer); } pPathComp = pOut; if (!renamed) { // Point pIn to beginning of our internal pathname. // If we are junking paths, then locate the file portion of the path. if (uO.jflag) pIn = (CHAR*)MBSRCHR(G.filename, '/'); if (pIn == NULL) pIn = G.filename; else ++pIn; } // Begin main loop through characters in filename. for ( ; (workch = *pIn) != '\0'; INCSTR(pIn)) { // Make sure we don't overflow our output buffer. if (pOut >= (szBuffer + countof(szBuffer) - 2)) { Info(slide, 1, ((char*)slide, "path too long: %s\n", FnFilter1(G.filename))); return MPN_ERR_TOOLONG; } // Examine the next character in our input buffer. switch (workch) { // Check for a directory wack. case '/': *pOut = '\0'; // Skip dir traversals unless they are explicitely allowed. if (strcmp(pPathComp, ".") == 0) { // don't bother appending "./" to the path *pPathComp = '\0'; } else if (!uO.ddotflag && strcmp(pPathComp, "..") == 0) { // "../" dir traversal detected, skip over it *pPathComp = '\0'; killed_ddot = TRUE; // set "show message" flag } // When path component is not empty, append it now. if (*pPathComp == '\0') { // Reset insert pos to start of path component. pOut = pPathComp; } else { if (!SmartCreateDirectory(__G__ szBuffer, &created_dir)) { Info(slide, 1, ((char*)slide, "failure extracting: %s\n", FnFilter1(G.filename))); return MPN_ERR_SKIP; } *(pOut++) = '\\'; pPathComp = pOut; // Remember start pos of new path component } pLastSemi = NULL; // Leave any directory semi-colons alone break; // Check for illegal characters and replace with underscore. case ':': case '\\': case '*': case '?': case '"': case '<': case '>': case '|': *(pOut++) = '_'; break; // Check for start of VMS version. case ';': pLastSemi = pOut; // Make note as to where we are. *(pOut++) = ';'; // Leave the semi-colon alone for now. break; default: // Allow European characters and spaces in filenames.#ifdef _MBCS if ((UCHAR)workch >= 0x20) { memcpy(pOut, pIn, CLEN(pIn)); INCSTR(pOut); } else { *(pOut++) = '_'; }#else *(pOut++) = (((UCHAR)workch >= 0x20) ? workch : '_');#endif } } // Show warning when stripping insecure "parent dir" path components if (killed_ddot && QCOND2) { Info(slide, 0, ((char *)slide, "warning: skipped \"../\" path component(s) in %s\n", FnFilter1(G.filename))); if (!(error & ~MPN_MASK)) error = (error & MPN_MASK) | PK_WARN; } // Done with output buffer, terminate it. *pOut = '\0'; // Remove any VMS version numbers if found (appended ";###"). if (pLastSemi) { // Walk over all digits following the semi-colon. for (pOut = pLastSemi + 1; (*pOut >= '0') && (*pOut <= '9'); pOut++); // If we reached the end, then nuke the semi-colon and digits. if (!*pOut) *pLastSemi = '\0'; } // Copy the mapped name back to the internal path buffer strcpy(G.filename, szBuffer);#ifdef POCKET_UNZIP // Fill in the mapped name buffer if the original caller requested us to. if (g_pExtractInfo->szMappedPath) { strcpy(g_pExtractInfo->szMappedPath, szBuffer); }#endif // If it is a directory, then display the "creating" status text. if ((pOut > szBuffer) && (lastchar(szBuffer, pOut-szBuffer) == '\\')) { if (created_dir) {#ifdef UNICODE TCHAR szFile[_MAX_PATH]; MBSTOTSTR(szFile, G.filename, countof(szFile));# define T_Fname szFile#else# define T_Fname G.filename#endif if (QCOND2) { Info(slide, 0, ((char *)slide, " creating: %-22s\n", FnFilter1(G.filename))); } // set file attributes: // The default for newly created directories is "DIR attribute // flags set", so there is no need to change attributes unless // one of the DOS style attribute flags is set. There is no need // to mask the readonly attribute, because it does not prevent // modifications in the new directory. if(G.pInfo->file_attr & (0x7F & ~FILE_ATTRIBUTE_DIRECTORY)) { if (!SetFileAttributes(T_Fname, G.pInfo->file_attr & 0x7F)) Info(slide, 1, ((char *)slide, "\nwarning (%d): could not set file attributes for %s\n", (int)GetLastError(), FnFilter1(G.filename))); } /* set dir time (note trailing '/') */ return (error & ~MPN_MASK) | MPN_CREATED_DIR; } /* dir existed already; don't look for data to extract */ return (error & ~MPN_MASK) | MPN_INF_SKIP; } return error;}//******************************************************************************// Called from PROCESS.Cint checkdir(__GPRO__ char *pathcomp, int flag) {#ifdef POCKET_UNZIP // This function is only called by free_G_buffers() from PROCESS.C with the // flag set to END. We have nothing to do, so we just return success. return MPN_OK;#else // !POCKET_UNZIP# define FN_MASK 7# define FUNCTION (flag & FN_MASK) int rc = MPN_OK; switch (FUNCTION) { case ROOT: { // User specified a root path. save the root without separator char* pathcompStart; if (pathcomp == NULL) { G.rootlen = 0; // trivial NULL clause... break; } if (G.rootlen > 0) break; // nothing to do, rootpath was already set G.rootlen = strlen(pathcomp); pathcompStart = pathcomp; // Strip the drive if given. CE does not support Drive if (pathcomp[1] == ':') { G.rootlen -= 2; pathcompStart += 2; } // Check for trailing separator, Strip if given // accomodate it if required. if (pathcomp[G.rootlen - 1] == '/' || pathcomp[G.rootlen - 1] == '\\') G.rootlen--; // Save the root memcpy(G.rootpath, pathcompStart, G.rootlen); G.rootpath[G.rootlen] = '\0'; // Check if directory exists and try to create when neccessary. if (!SmartCreateDirectory(__G__ G.rootpath, NULL)) { rc = MPN_ERR_SKIP; // Create directory failed } // Add trailing path separator G.rootpath[G.rootlen++] = '\\'; G.rootpath[G.rootlen] = '0'; break; } case END: Trace((stderr, "freeing rootpath\n")); if (G.rootlen > 0) { G.rootlen = 0; G.rootpath[0] = '\0'; } break; default: rc = MPN_INVALID; /* should never reach */ break; } return rc;#endif // !POCKET_UNZIP} /* end function checkdir() */#ifdef POCKET_UNZIP//******************************************************************************// Called from EXTRACT.C and LIST.Cint match(ZCONST char *string, ZCONST char *pattern, int ignore_case __WDLPRO){ // match() for the other ports compares a file in the Zip file with some // command line file pattern. In our case, we always pass in exact matches, // so we can simply do a string compare to see if we have a match. return (strcmp(string, pattern) == 0);}//******************************************************************************// Called from PROCESS.Cint iswild(ZCONST char *pattern) { // Our file patterns never contain wild characters. They are always exact // matches of file names in our Zip file. return FALSE;}#else // !POCKET_UNZIP/************************//* Function version() *//************************/void version(__GPRO){ // Dummy function, does nothing.}#ifndef WINDLL/* Console input not supported on CE so just return -1 */int getch_win32(void){ return -1;}#endif /* !WINDLL */#endif // !POCKET_UNZIP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -