ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

cabinet_main.c
Go to the documentation of this file.
00001 /*
00002  * cabinet.dll main
00003  *
00004  * Copyright 2002 Patrik Stridvall
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include "config.h"
00022 
00023 #include <assert.h>
00024 #include <stdarg.h>
00025 #include <string.h>
00026 
00027 #include "windef.h"
00028 #include "winbase.h"
00029 #include "winerror.h"
00030 #define NO_SHLWAPI_REG
00031 #include "shlwapi.h"
00032 #undef NO_SHLWAPI_REG
00033 
00034 #include "cabinet.h"
00035 
00036 #include "wine/debug.h"
00037 
00038 WINE_DEFAULT_DEBUG_CHANNEL(cabinet);
00039 
00040 
00041 /***********************************************************************
00042  * DllGetVersion (CABINET.2)
00043  *
00044  * Retrieves version information of the 'CABINET.DLL'
00045  *
00046  * PARAMS
00047  *     pdvi [O] pointer to version information structure.
00048  *
00049  * RETURNS
00050  *     Success: S_OK
00051  *     Failure: E_INVALIDARG
00052  *
00053  * NOTES
00054  *     Supposedly returns version from IE6SP1RP1
00055  */
00056 HRESULT WINAPI DllGetVersion (DLLVERSIONINFO *pdvi)
00057 {
00058   WARN("hmmm... not right version number \"5.1.1106.1\"?\n");
00059 
00060   if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) return E_INVALIDARG;
00061 
00062   pdvi->dwMajorVersion = 5;
00063   pdvi->dwMinorVersion = 1;
00064   pdvi->dwBuildNumber = 1106;
00065   pdvi->dwPlatformID = 1;
00066 
00067   return S_OK;
00068 }
00069 
00070 /* FDI callback functions */
00071 
00072 static void * CDECL mem_alloc(ULONG cb)
00073 {
00074     return HeapAlloc(GetProcessHeap(), 0, cb);
00075 }
00076 
00077 static void CDECL mem_free(void *memory)
00078 {
00079     HeapFree(GetProcessHeap(), 0, memory);
00080 }
00081 
00082 static INT_PTR CDECL fdi_open(char *pszFile, int oflag, int pmode)
00083 {
00084     HANDLE handle;
00085     DWORD dwAccess = 0;
00086     DWORD dwShareMode = 0;
00087     DWORD dwCreateDisposition;
00088 
00089     switch (oflag & _O_ACCMODE)
00090     {
00091         case _O_RDONLY:
00092             dwAccess = GENERIC_READ;
00093             dwShareMode = FILE_SHARE_READ | FILE_SHARE_DELETE;
00094             break;
00095         case _O_WRONLY:
00096             dwAccess = GENERIC_WRITE;
00097             dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
00098             break;
00099         case _O_RDWR:
00100             dwAccess = GENERIC_READ | GENERIC_WRITE;
00101             dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
00102             break;
00103     }
00104 
00105     if (oflag & _O_CREAT)
00106     {
00107         dwCreateDisposition = OPEN_ALWAYS;
00108         if (oflag & _O_EXCL) dwCreateDisposition = CREATE_NEW;
00109         else if (oflag & _O_TRUNC) dwCreateDisposition = CREATE_ALWAYS;
00110     }
00111     else
00112     {
00113         dwCreateDisposition = OPEN_EXISTING;
00114         if (oflag & _O_TRUNC) dwCreateDisposition = TRUNCATE_EXISTING;
00115     }
00116 
00117     handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
00118                          dwCreateDisposition, 0, NULL);
00119 
00120     return (INT_PTR) handle;
00121 }
00122 
00123 static UINT CDECL fdi_read(INT_PTR hf, void *pv, UINT cb)
00124 {
00125     HANDLE handle = (HANDLE) hf;
00126     DWORD dwRead;
00127     
00128     if (ReadFile(handle, pv, cb, &dwRead, NULL))
00129         return dwRead;
00130 
00131     return 0;
00132 }
00133 
00134 static UINT CDECL fdi_write(INT_PTR hf, void *pv, UINT cb)
00135 {
00136     HANDLE handle = (HANDLE) hf;
00137     DWORD dwWritten;
00138 
00139     if (WriteFile(handle, pv, cb, &dwWritten, NULL))
00140         return dwWritten;
00141 
00142     return 0;
00143 }
00144 
00145 static int CDECL fdi_close(INT_PTR hf)
00146 {
00147     HANDLE handle = (HANDLE) hf;
00148     return CloseHandle(handle) ? 0 : -1;
00149 }
00150 
00151 static LONG CDECL fdi_seek(INT_PTR hf, LONG dist, int seektype)
00152 {
00153     HANDLE handle = (HANDLE) hf;
00154     return SetFilePointer(handle, dist, NULL, seektype);
00155 }
00156 
00157 static void fill_file_node(struct FILELIST *pNode, LPCSTR szFilename)
00158 {
00159     pNode->next = NULL;
00160     pNode->DoExtract = FALSE;
00161 
00162     pNode->FileName = HeapAlloc(GetProcessHeap(), 0, strlen(szFilename) + 1);
00163     lstrcpyA(pNode->FileName, szFilename);
00164 }
00165 
00166 static BOOL file_in_list(struct FILELIST *pNode, LPCSTR szFilename,
00167                          struct FILELIST **pOut)
00168 {
00169     while (pNode)
00170     {
00171         if (!lstrcmpiA(pNode->FileName, szFilename))
00172         {
00173             if (pOut)
00174                 *pOut = pNode;
00175 
00176             return TRUE;
00177         }
00178 
00179         pNode = pNode->next;
00180     }
00181 
00182     return FALSE;
00183 }
00184 
00185 static INT_PTR CDECL fdi_notify_extract(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
00186 {
00187     switch (fdint)
00188     {
00189         case fdintCOPY_FILE:
00190         {
00191             struct FILELIST *fileList, *node = NULL;
00192             SESSION *pDestination = pfdin->pv;
00193             LPSTR szFullPath, szDirectory;
00194             HANDLE hFile = 0;
00195             DWORD dwSize;
00196 
00197             dwSize = lstrlenA(pDestination->Destination) +
00198                     lstrlenA("\\") + lstrlenA(pfdin->psz1) + 1;
00199             szFullPath = HeapAlloc(GetProcessHeap(), 0, dwSize);
00200 
00201             lstrcpyA(szFullPath, pDestination->Destination);
00202             lstrcatA(szFullPath, "\\");
00203             lstrcatA(szFullPath, pfdin->psz1);
00204 
00205             /* pull out the destination directory string from the full path */
00206             dwSize = strrchr(szFullPath, '\\') - szFullPath + 1;
00207             szDirectory = HeapAlloc(GetProcessHeap(), 0, dwSize);
00208             lstrcpynA(szDirectory, szFullPath, dwSize);
00209 
00210             pDestination->FileSize += pfdin->cb;
00211 
00212             if (pDestination->Operation & EXTRACT_FILLFILELIST)
00213             {
00214                 fileList = HeapAlloc(GetProcessHeap(), 0,
00215                                      sizeof(struct FILELIST));
00216 
00217                 fill_file_node(fileList, pfdin->psz1);
00218                 fileList->DoExtract = TRUE;
00219                 fileList->next = pDestination->FileList;
00220                 pDestination->FileList = fileList;
00221                 lstrcpyA(pDestination->CurrentFile, szFullPath);
00222                 pDestination->FileCount++;
00223             }
00224 
00225             if ((pDestination->Operation & EXTRACT_EXTRACTFILES) ||
00226                 file_in_list(pDestination->FilterList, pfdin->psz1, NULL))
00227             {
00228         /* find the file node */
00229                 file_in_list(pDestination->FileList, pfdin->psz1, &node);
00230 
00231                 if (node && !node->DoExtract)
00232                 {
00233                     HeapFree(GetProcessHeap(), 0, szFullPath);
00234                     HeapFree(GetProcessHeap(), 0, szDirectory);
00235                     return 0;
00236                 }
00237 
00238                 /* create the destination directory if it doesn't exist */
00239                 if (GetFileAttributesA(szDirectory) == INVALID_FILE_ATTRIBUTES)
00240                 {
00241                     char *ptr;
00242 
00243                     for(ptr = szDirectory + strlen(pDestination->Destination)+1; *ptr; ptr++) {
00244                         if(*ptr == '\\') {
00245                             *ptr = 0;
00246                             CreateDirectoryA(szDirectory, NULL);
00247                             *ptr = '\\';
00248                         }
00249                     }
00250                     CreateDirectoryA(szDirectory, NULL);
00251                 }
00252 
00253                 hFile = CreateFileA(szFullPath, GENERIC_READ | GENERIC_WRITE, 0, NULL,
00254                                     CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
00255 
00256                 if (hFile == INVALID_HANDLE_VALUE)
00257                     hFile = 0;
00258                 else if (node)
00259                     node->DoExtract = FALSE;
00260             }
00261 
00262             HeapFree(GetProcessHeap(), 0, szFullPath);
00263             HeapFree(GetProcessHeap(), 0, szDirectory);
00264 
00265             return (INT_PTR) hFile;
00266         }
00267 
00268         case fdintCLOSE_FILE_INFO:
00269         {
00270             FILETIME ft;
00271             FILETIME ftLocal;
00272             HANDLE handle = (HANDLE) pfdin->hf;
00273 
00274             if (!DosDateTimeToFileTime(pfdin->date, pfdin->time, &ft))
00275                 return FALSE;
00276 
00277             if (!LocalFileTimeToFileTime(&ft, &ftLocal))
00278                 return FALSE;
00279 
00280             if (!SetFileTime(handle, &ftLocal, 0, &ftLocal))
00281                 return FALSE;
00282 
00283             CloseHandle(handle);
00284             return TRUE;
00285         }
00286 
00287         default:
00288             return 0;
00289     }
00290 }
00291 
00292 /***********************************************************************
00293  * Extract (CABINET.3)
00294  *
00295  * Extracts the contents of the cabinet file to the specified
00296  * destination.
00297  *
00298  * PARAMS
00299  *   dest      [I/O] Controls the operation of Extract.  See NOTES.
00300  *   szCabName [I] Filename of the cabinet to extract.
00301  *
00302  * RETURNS
00303  *     Success: S_OK.
00304  *     Failure: E_FAIL.
00305  *
00306  * NOTES
00307  *   The following members of the dest struct control the operation
00308  *   of Extract:
00309  *       FileSize    [O] The size of all files extracted up to CurrentFile.
00310  *       Error       [O] The error in case the extract operation fails.
00311  *       FileList    [I] A linked list of filenames.  Extract only extracts
00312  *                       files from the cabinet that are in this list.
00313  *       FileCount   [O] Contains the number of files in FileList on
00314  *                       completion.
00315  *       Operation   [I] See Operation.
00316  *       Destination [I] The destination directory.
00317  *       CurrentFile [O] The last file extracted.
00318  *       FilterList  [I] A linked list of files that should not be extracted.
00319  *
00320  *   Operation
00321  *     If Operation contains EXTRACT_FILLFILELIST, then FileList will be
00322  *     filled with all the files in the cabinet.  If Operation contains
00323  *     EXTRACT_EXTRACTFILES, then only the files in the FileList will
00324  *     be extracted from the cabinet.  EXTRACT_FILLFILELIST can be called
00325  *     by itself, but EXTRACT_EXTRACTFILES must have a valid FileList
00326  *     in order to succeed.  If Operation contains both EXTRACT_FILLFILELIST
00327  *     and EXTRACT_EXTRACTFILES, then all the files in the cabinet
00328  *     will be extracted.
00329  */
00330 HRESULT WINAPI Extract(SESSION *dest, LPCSTR szCabName)
00331 {
00332     HRESULT res = S_OK;
00333     HFDI hfdi;
00334     char *str, *end, *path = NULL, *name = NULL;
00335 
00336     TRACE("(%p, %s)\n", dest, szCabName);
00337 
00338     hfdi = FDICreate(mem_alloc,
00339                      mem_free,
00340                      fdi_open,
00341                      fdi_read,
00342                      fdi_write,
00343                      fdi_close,
00344                      fdi_seek,
00345                      cpuUNKNOWN,
00346                      &dest->Error);
00347 
00348     if (!hfdi)
00349         return E_FAIL;
00350 
00351     if (GetFileAttributesA(dest->Destination) == INVALID_FILE_ATTRIBUTES)
00352     {
00353         res = S_OK;
00354         goto end;
00355     }
00356 
00357     /* split the cabinet name into path + name */
00358     str = HeapAlloc(GetProcessHeap(), 0, lstrlenA(szCabName)+1);
00359     if (!str)
00360     {
00361         res = E_OUTOFMEMORY;
00362         goto end;
00363     }
00364     lstrcpyA(str, szCabName);
00365 
00366     if ((end = strrchr(str, '\\')))
00367     {
00368         end++;
00369         name = HeapAlloc( GetProcessHeap(), 0, strlen(end) + 1 );
00370         if (!name)
00371         {
00372             res = E_OUTOFMEMORY;
00373             goto end;
00374         }
00375         strcpy( name, end );
00376         *end = 0;
00377         path = str;
00378     }
00379     else
00380     {
00381         name = str;
00382         path = NULL;
00383     }
00384 
00385     dest->FileSize = 0;
00386 
00387     if (!FDICopy(hfdi, name, path, 0,
00388          fdi_notify_extract, NULL, dest))
00389         res = HRESULT_FROM_WIN32(GetLastError());
00390 
00391 end:
00392     HeapFree(GetProcessHeap(), 0, path);
00393     HeapFree(GetProcessHeap(), 0, name);
00394     FDIDestroy(hfdi);
00395     return res;
00396 }

Generated on Sat May 26 2012 04:21:27 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.