/* returns the number of files that are in both the linked list and szFileList */ static DWORD fill_file_list(SESSION *session, LPCSTR szCabName, LPCSTR szFileList) { DWORD dwNumFound = 0; struct FILELIST *pNode; session->Operation |= EXTRACT_FILLFILELIST; if (pExtract(session, szCabName) != S_OK) { session->Operation &= ~EXTRACT_FILLFILELIST; return -1; } pNode = session->FileList; while (pNode) { if (!file_in_list(pNode->FileName, szFileList)) pNode->DoExtract = FALSE; else dwNumFound++; pNode = pNode->next; } session->Operation &= ~EXTRACT_FILLFILELIST; return dwNumFound; }
static INT_PTR CDECL fdi_notify_extract(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) { switch (fdint) { case fdintCOPY_FILE: { struct FILELIST *fileList, *node = NULL; SESSION *pDestination = pfdin->pv; LPSTR szFullPath, szDirectory; HANDLE hFile = 0; DWORD dwSize; dwSize = lstrlenA(pDestination->Destination) + lstrlenA("\\") + lstrlenA(pfdin->psz1) + 1; szFullPath = HeapAlloc(GetProcessHeap(), 0, dwSize); lstrcpyA(szFullPath, pDestination->Destination); lstrcatA(szFullPath, "\\"); lstrcatA(szFullPath, pfdin->psz1); /* pull out the destination directory string from the full path */ dwSize = strrchr(szFullPath, '\\') - szFullPath + 1; szDirectory = HeapAlloc(GetProcessHeap(), 0, dwSize); lstrcpynA(szDirectory, szFullPath, dwSize); pDestination->FileSize += pfdin->cb; if (pDestination->Operation & EXTRACT_FILLFILELIST) { fileList = HeapAlloc(GetProcessHeap(), 0, sizeof(struct FILELIST)); fill_file_node(fileList, pfdin->psz1); fileList->DoExtract = TRUE; fileList->next = pDestination->FileList; pDestination->FileList = fileList; lstrcpyA(pDestination->CurrentFile, szFullPath); pDestination->FileCount++; } if ((pDestination->Operation & EXTRACT_EXTRACTFILES) || file_in_list(pDestination->FilterList, pfdin->psz1, NULL)) { /* find the file node */ file_in_list(pDestination->FileList, pfdin->psz1, &node); if (node && !node->DoExtract) { HeapFree(GetProcessHeap(), 0, szFullPath); HeapFree(GetProcessHeap(), 0, szDirectory); return 0; } /* create the destination directory if it doesn't exist */ if (GetFileAttributesA(szDirectory) == INVALID_FILE_ATTRIBUTES) { char *ptr; for(ptr = szDirectory + strlen(pDestination->Destination)+1; *ptr; ptr++) { if(*ptr == '\\') { *ptr = 0; CreateDirectoryA(szDirectory, NULL); *ptr = '\\'; } } CreateDirectoryA(szDirectory, NULL); } hFile = CreateFileA(szFullPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) hFile = 0; else if (node) node->DoExtract = FALSE; } HeapFree(GetProcessHeap(), 0, szFullPath); HeapFree(GetProcessHeap(), 0, szDirectory); return (INT_PTR) hFile; } case fdintCLOSE_FILE_INFO: { FILETIME ft; FILETIME ftLocal; HANDLE handle = (HANDLE) pfdin->hf; if (!DosDateTimeToFileTime(pfdin->date, pfdin->time, &ft)) return FALSE; if (!LocalFileTimeToFileTime(&ft, &ftLocal)) return FALSE; if (!SetFileTime(handle, &ftLocal, 0, &ftLocal)) return FALSE; CloseHandle(handle); return TRUE; } default: return 0; } }