WINE_DEFAULT_DEBUG_CHANNEL(cabinet);
-/* the following defintions are copied from msvcrt/fcntl.h */
-
-#define _O_RDONLY 0
-#define _O_WRONLY 1
-#define _O_RDWR 2
-#define _O_ACCMODE (_O_RDONLY|_O_WRONLY|_O_RDWR)
-
/***********************************************************************
* DllGetVersion (CABINET.2)
HANDLE handle;
DWORD dwAccess = 0;
DWORD dwShareMode = 0;
- DWORD dwCreateDisposition = OPEN_EXISTING;
+ DWORD dwCreateDisposition;
switch (oflag & _O_ACCMODE)
{
break;
}
- if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
- dwCreateDisposition = OPEN_EXISTING;
+ if (oflag & _O_CREAT)
+ {
+ dwCreateDisposition = OPEN_ALWAYS;
+ if (oflag & _O_EXCL) dwCreateDisposition = CREATE_NEW;
+ else if (oflag & _O_TRUNC) dwCreateDisposition = CREATE_ALWAYS;
+ }
else
- dwCreateDisposition = CREATE_NEW;
+ {
+ dwCreateDisposition = OPEN_EXISTING;
+ if (oflag & _O_TRUNC) dwCreateDisposition = TRUNCATE_EXISTING;
+ }
handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
dwCreateDisposition, 0, NULL);
return SetFilePointer(handle, dist, NULL, seektype);
}
-static void fill_file_node(struct ExtractFileList *pNode, LPSTR szFilename)
+static void fill_file_node(struct FILELIST *pNode, LPCSTR szFilename)
{
pNode->next = NULL;
- pNode->unknown = TRUE;
+ pNode->DoExtract = FALSE;
- pNode->filename = HeapAlloc(GetProcessHeap(), 0, strlen(szFilename) + 1);
- lstrcpyA(pNode->filename, szFilename);
+ pNode->FileName = HeapAlloc(GetProcessHeap(), 0, strlen(szFilename) + 1);
+ lstrcpyA(pNode->FileName, szFilename);
}
-static BOOL file_in_list(struct ExtractFileList *pNode, LPSTR szFilename)
+static BOOL file_in_list(struct FILELIST *pNode, LPCSTR szFilename,
+ struct FILELIST **pOut)
{
while (pNode)
{
- if (!lstrcmpiA(pNode->filename, szFilename))
+ if (!lstrcmpiA(pNode->FileName, szFilename))
+ {
+ if (pOut)
+ *pOut = pNode;
+
return TRUE;
+ }
pNode = pNode->next;
}
{
case fdintCOPY_FILE:
{
- struct ExtractFileList **fileList;
- EXTRACTdest *pDestination = pfdin->pv;
+ struct FILELIST *fileList, *node = NULL;
+ SESSION *pDestination = pfdin->pv;
LPSTR szFullPath, szDirectory;
HANDLE hFile = 0;
DWORD dwSize;
- dwSize = lstrlenA(pDestination->directory) +
+ dwSize = lstrlenA(pDestination->Destination) +
lstrlenA("\\") + lstrlenA(pfdin->psz1) + 1;
szFullPath = HeapAlloc(GetProcessHeap(), 0, dwSize);
- lstrcpyA(szFullPath, pDestination->directory);
+ lstrcpyA(szFullPath, pDestination->Destination);
lstrcatA(szFullPath, "\\");
lstrcatA(szFullPath, pfdin->psz1);
szDirectory = HeapAlloc(GetProcessHeap(), 0, dwSize);
lstrcpynA(szDirectory, szFullPath, dwSize);
- if (pDestination->flags & EXTRACT_FILLFILELIST)
- {
- fileList = &pDestination->filelist;
-
- while (*fileList)
- fileList = &((*fileList)->next);
-
- *fileList = HeapAlloc(GetProcessHeap(), 0,
- sizeof(struct ExtractFileList));
+ pDestination->FileSize += pfdin->cb;
- fill_file_node(*fileList, pfdin->psz1);
- lstrcpyA(pDestination->lastfile, szFullPath);
- pDestination->filecount++;
+ 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->flags & EXTRACT_EXTRACTFILES)
+ if ((pDestination->Operation & EXTRACT_EXTRACTFILES) ||
+ file_in_list(pDestination->FilterList, pfdin->psz1, NULL))
{
- /* skip this file it it's not in the file list */
- if (!file_in_list(pDestination->filelist, pfdin->psz1))
+ /* 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)
if (hFile == INVALID_HANDLE_VALUE)
hFile = 0;
+ else if (node)
+ node->DoExtract = FALSE;
}
HeapFree(GetProcessHeap(), 0, szFullPath);
* NOTES
* The following members of the dest struct control the operation
* of Extract:
- * filelist [I] A linked list of filenames. Extract only extracts
- * files from the cabinet that are in this list.
- * filecount [O] Contains the number of files in filelist on
- * completion.
- * flags [I] See Operation.
- * directory [I] The destination directory.
- * lastfile [O] The last file extracted.
+ * FileSize [O] The size of all files extracted up to CurrentFile.
+ * Error [O] The error in case the extract operation fails.
+ * FileList [I] A linked list of filenames. Extract only extracts
+ * files from the cabinet that are in this list.
+ * FileCount [O] Contains the number of files in FileList on
+ * completion.
+ * Operation [I] See Operation.
+ * Destination [I] The destination directory.
+ * CurrentFile [O] The last file extracted.
+ * FilterList [I] A linked list of files that should not be extracted.
*
* Operation
- * If flags contains EXTRACT_FILLFILELIST, then filelist will be
- * filled with all the files in the cabinet. If flags contains
- * EXTRACT_EXTRACTFILES, then only the files in the filelist will
+ * If Operation contains EXTRACT_FILLFILELIST, then FileList will be
+ * filled with all the files in the cabinet. If Operation contains
+ * EXTRACT_EXTRACTFILES, then only the files in the FileList will
* be extracted from the cabinet. EXTRACT_FILLFILELIST can be called
- * by itself, but EXTRACT_EXTRACTFILES must have a valid filelist
- * in order to succeed. If flags contains both EXTRACT_FILLFILELIST
+ * by itself, but EXTRACT_EXTRACTFILES must have a valid FileList
+ * in order to succeed. If Operation contains both EXTRACT_FILLFILELIST
* and EXTRACT_EXTRACTFILES, then all the files in the cabinet
* will be extracted.
*/
-HRESULT WINAPI Extract(EXTRACTdest *dest, LPCSTR szCabName)
+HRESULT WINAPI Extract(SESSION *dest, LPCSTR szCabName)
{
HRESULT res = S_OK;
HFDI hfdi;
- ERF erf;
+ char *str, *path, *name;
TRACE("(%p, %s)\n", dest, szCabName);
fdi_close,
fdi_seek,
cpuUNKNOWN,
- &erf);
+ &dest->Error);
if (!hfdi)
return E_FAIL;
- if (GetFileAttributesA(dest->directory) == INVALID_FILE_ATTRIBUTES)
- return S_OK;
+ if (GetFileAttributesA(dest->Destination) == INVALID_FILE_ATTRIBUTES)
+ {
+ res = S_OK;
+ goto end;
+ }
+
+ /* split the cabinet name into path + name */
+ str = HeapAlloc(GetProcessHeap(), 0, lstrlenA(szCabName)+1);
+ if (!str)
+ {
+ res = E_OUTOFMEMORY;
+ goto end;
+ }
+ lstrcpyA(str, szCabName);
- if (!FDICopy(hfdi, (LPSTR)szCabName, "", 0,
+ path = str;
+ name = strrchr(path, '\\');
+ if (name)
+ *name++ = 0;
+ else
+ {
+ name = path;
+ path = NULL;
+ }
+
+ dest->FileSize = 0;
+
+ if (!FDICopy(hfdi, name, path, 0,
fdi_notify_extract, NULL, dest))
- res = E_FAIL;
+ res = HRESULT_FROM_WIN32(GetLastError());
+
+ HeapFree(GetProcessHeap(), 0, str);
+end:
FDIDestroy(hfdi);