diff --git a/dlls/advpack/files.c b/dlls/advpack/files.c index d0f948caca3..7dc816f46bc 100644 --- a/dlls/advpack/files.c +++ b/dlls/advpack/files.c @@ -523,7 +523,7 @@ HRESULT WINAPI DelNodeRunDLL32W(HWND hWnd, HINSTANCE hInst, LPWSTR cmdline, INT struct FILELIST{ LPSTR FileName; struct FILELIST *next; - BOOL Extracted; + BOOL DoExtract; }; typedef struct { @@ -621,14 +621,12 @@ static BOOL file_in_list(LPCSTR szFile, LPCSTR szFileList) return FALSE; } -/* removes nodes from the linked list that aren't specified in szFileList - * returns the number of files that are in both the linked list and szFileList - */ + +/* 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; - struct FILELIST *prev = NULL; session->Operation |= EXTRACT_FILLFILELIST; if (pExtract(session, szCabName)) @@ -640,24 +638,12 @@ static DWORD fill_file_list(SESSION *session, LPCSTR szCabName, LPCSTR szFileLis pNode = session->FileList; while (pNode) { - if (file_in_list(pNode->FileName, szFileList)) - { - prev = pNode; - pNode = pNode->next; - dwNumFound++; - } - else if (prev) - { - prev->next = pNode->next; - free_file_node(pNode); - pNode = prev->next; - } + if (!file_in_list(pNode->FileName, szFileList)) + pNode->DoExtract = FALSE; else - { - session->FileList = pNode->next; - free_file_node(pNode); - pNode = session->FileList; - } + dwNumFound++; + + pNode = pNode->next; } session->Operation &= ~EXTRACT_FILLFILELIST; diff --git a/dlls/cabinet/cabinet.h b/dlls/cabinet/cabinet.h index 3b72ff8da61..f566124c173 100644 --- a/dlls/cabinet/cabinet.h +++ b/dlls/cabinet/cabinet.h @@ -638,7 +638,7 @@ static const cab_UWORD Zipmask[17] = { struct FILELIST{ LPSTR FileName; struct FILELIST *next; - BOOL Extracted; + BOOL DoExtract; }; typedef struct { diff --git a/dlls/cabinet/cabinet_main.c b/dlls/cabinet/cabinet_main.c index 50ef06e8afd..9e2c18a047e 100644 --- a/dlls/cabinet/cabinet_main.c +++ b/dlls/cabinet/cabinet_main.c @@ -157,7 +157,7 @@ static long fdi_seek(INT_PTR hf, long dist, int seektype) static void fill_file_node(struct FILELIST *pNode, LPCSTR szFilename) { pNode->next = NULL; - pNode->Extracted = FALSE; + pNode->DoExtract = FALSE; pNode->FileName = HeapAlloc(GetProcessHeap(), 0, strlen(szFilename) + 1); lstrcpyA(pNode->FileName, szFilename); @@ -188,7 +188,7 @@ static INT_PTR fdi_notify_extract(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pf { case fdintCOPY_FILE: { - struct FILELIST *fileList, *node; + struct FILELIST *fileList, *node = NULL; SESSION *pDestination = pfdin->pv; LPSTR szFullPath, szDirectory; HANDLE hFile = 0; @@ -215,7 +215,7 @@ static INT_PTR fdi_notify_extract(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pf sizeof(struct FILELIST)); fill_file_node(fileList, pfdin->psz1); - fileList->Extracted = TRUE; + fileList->DoExtract = TRUE; fileList->next = pDestination->FileList; pDestination->FileList = fileList; lstrcpyA(pDestination->CurrentFile, szFullPath); @@ -225,8 +225,10 @@ static INT_PTR fdi_notify_extract(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pf if ((pDestination->Operation & EXTRACT_EXTRACTFILES) || file_in_list(pDestination->FilterList, pfdin->psz1, NULL)) { - /* skip this file if it is not in the file list */ - if (!file_in_list(pDestination->FileList, pfdin->psz1, &node)) + /* find the file node */ + file_in_list(pDestination->FileList, pfdin->psz1, &node); + + if (node && !node->DoExtract) return 0; /* create the destination directory if it doesn't exist */ @@ -238,8 +240,8 @@ static INT_PTR fdi_notify_extract(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pf if (hFile == INVALID_HANDLE_VALUE) hFile = 0; - else - node->Extracted = FALSE; + else if (node) + node->DoExtract = FALSE; } HeapFree(GetProcessHeap(), 0, szFullPath); diff --git a/dlls/cabinet/tests/extract.c b/dlls/cabinet/tests/extract.c index 8cadfe202d8..5ce5ba8608e 100644 --- a/dlls/cabinet/tests/extract.c +++ b/dlls/cabinet/tests/extract.c @@ -39,7 +39,7 @@ struct FILELIST{ LPSTR FileName; struct FILELIST *next; - BOOL Extracted; + BOOL DoExtract; }; typedef struct { @@ -314,7 +314,7 @@ static void create_cab_file(void) ok(res, "Failed to destroy the cabinet\n"); } -static BOOL check_list(struct FILELIST **node, const char *filename, BOOL extracted) +static BOOL check_list(struct FILELIST **node, const char *filename, BOOL do_extract) { if (!*node) return FALSE; @@ -322,7 +322,7 @@ static BOOL check_list(struct FILELIST **node, const char *filename, BOOL extrac if (lstrcmpA((*node)->FileName, filename)) return FALSE; - if ((*node)->Extracted != extracted) + if ((*node)->DoExtract != do_extract) return FALSE; *node = (*node)->next; @@ -445,7 +445,9 @@ static void test_Extract(void) ok(!*session.Reserved, "Expected empty string, got %s\n", session.Reserved); ok(!session.FilterList, "Expected empty filter list\n"); ok(!DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to not exist\n"); + ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to not exist\n"); ok(!DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to not exist\n"); + ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n"); ok(check_list(&node, "testdir\\d.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "testdir\\c.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "b.txt", FALSE), "list entry wrong\n"); @@ -472,13 +474,10 @@ static void test_Extract(void) "Expected dest\\testdir\\d.txt, got %s\n", session.CurrentFile); ok(!*session.Reserved, "Expected empty string, got %s\n", session.Reserved); ok(!session.FilterList, "Expected empty filter list\n"); - todo_wine - { - ok(DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to exist\n"); - ok(DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to exist\n"); - ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to not exist\n"); - ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n"); - } + ok(DeleteFileA("dest\\a.txt"), "Expected dest\\a.txt to exist\n"); + ok(DeleteFileA("dest\\testdir\\c.txt"), "Expected dest\\testdir\\c.txt to exist\n"); + ok(!DeleteFileA("dest\\b.txt"), "Expected dest\\b.txt to not exist\n"); + ok(!DeleteFileA("dest\\testdir\\d.txt"), "Expected dest\\testdir\\d.txt to not exist\n"); ok(check_list(&node, "testdir\\d.txt", FALSE), "list entry wrong\n"); ok(!check_list(&node, "testdir\\c.txt", FALSE), "list entry wrong\n"); ok(check_list(&node, "b.txt", FALSE), "list entry wrong\n");