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

setupcab.c
Go to the documentation of this file.
00001 /* 
00002  * Setupapi cabinet routines
00003  *
00004  * Copyright 2003 Gregory M. Turner
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  * Many useful traces are commented in code, uncomment them if you have
00022  * trouble and run with WINEDEBUG=+setupapi
00023  * 
00024  */
00025 
00026 #include "setupapi_private.h"
00027 
00028 HINSTANCE hInstance = 0;
00029 OSVERSIONINFOW OsVersionInfo;
00030 
00031 static HINSTANCE CABINET_hInstance = 0;
00032 
00033 static HFDI (__cdecl *sc_FDICreate)(PFNALLOC, PFNFREE, PFNOPEN,
00034                 PFNREAD, PFNWRITE, PFNCLOSE, PFNSEEK, int, PERF);
00035 
00036 static BOOL (__cdecl *sc_FDICopy)(HFDI, char *, char *, int,
00037                 PFNFDINOTIFY, PFNFDIDECRYPT, void *);
00038 
00039 static BOOL (__cdecl *sc_FDIDestroy)(HFDI);
00040 
00041 #define SC_HSC_A_MAGIC 0xACABFEED
00042 typedef struct {
00043   UINT magic;
00044   HFDI hfdi;
00045   PSP_FILE_CALLBACK_A msghandler;
00046   PVOID context;
00047   CHAR most_recent_cabinet_name[MAX_PATH];
00048 } SC_HSC_A, *PSC_HSC_A;
00049 
00050 #define SC_HSC_W_MAGIC 0x0CABFEED
00051 typedef struct {
00052   UINT magic;
00053   HFDI hfdi;
00054   PSP_FILE_CALLBACK_W msghandler;
00055   PVOID context;
00056   WCHAR most_recent_cabinet_name[MAX_PATH];
00057 } SC_HSC_W, *PSC_HSC_W;
00058 
00059 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
00060 
00061 static BOOL LoadCABINETDll(void)
00062 {
00063   if (!CABINET_hInstance) {
00064     CABINET_hInstance = LoadLibraryA("cabinet.dll");
00065     if (CABINET_hInstance)  {
00066       sc_FDICreate = (void *)GetProcAddress(CABINET_hInstance, "FDICreate");
00067       sc_FDICopy = (void *)GetProcAddress(CABINET_hInstance, "FDICopy");
00068       sc_FDIDestroy = (void *)GetProcAddress(CABINET_hInstance, "FDIDestroy");
00069       return TRUE;
00070     } else {
00071       ERR("load cabinet dll failed.\n");
00072       return FALSE;
00073     }
00074   } else
00075     return TRUE;
00076 }
00077 
00078 static void UnloadCABINETDll(void)
00079 {
00080   if (CABINET_hInstance) {
00081     FreeLibrary(CABINET_hInstance);
00082     CABINET_hInstance = 0;
00083   }
00084 }
00085 
00086 /* FDICreate callbacks */
00087 
00088 static void *sc_cb_alloc(ULONG cb)
00089 {
00090   return HeapAlloc(GetProcessHeap(), 0, cb);
00091 }
00092 
00093 static void sc_cb_free(void *pv)
00094 {
00095   HeapFree(GetProcessHeap(), 0, pv);
00096 }
00097 
00098 static INT_PTR sc_cb_open(char *pszFile, int oflag, int pmode)
00099 {
00100   DWORD creation = 0, sharing = 0;
00101   int ioflag = 0;
00102   INT_PTR ret = 0;
00103   SECURITY_ATTRIBUTES sa;
00104 
00105   /* TRACE("(pszFile == %s, oflag == %d, pmode == %d)\n", debugstr_a(pszFile), oflag, pmode); */
00106 
00107   switch(oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
00108   case _O_RDONLY:
00109     ioflag |= GENERIC_READ;
00110     break;
00111   case _O_WRONLY:
00112     ioflag |= GENERIC_WRITE;
00113     break;
00114   case _O_RDWR:
00115     ioflag |= GENERIC_READ & GENERIC_WRITE;
00116     break;
00117   case _O_WRONLY | _O_RDWR: /* hmmm.. */
00118     ERR("_O_WRONLY & _O_RDWR in oflag?\n");
00119     return -1;
00120   }
00121 
00122   if (oflag & _O_CREAT) {
00123     if (oflag & _O_EXCL)
00124       creation = CREATE_NEW;
00125     else if (oflag & _O_TRUNC)
00126       creation = CREATE_ALWAYS;
00127     else
00128       creation = OPEN_ALWAYS;
00129   } else  /* no _O_CREAT */ {
00130     if (oflag & _O_TRUNC)
00131       creation = TRUNCATE_EXISTING;
00132     else
00133       creation = OPEN_EXISTING;
00134   }
00135 
00136   switch( pmode & 0x70 ) {
00137     case _SH_DENYRW:
00138       sharing = 0L;
00139       break;
00140     case _SH_DENYWR:
00141       sharing = FILE_SHARE_READ;
00142       break;
00143     case _SH_DENYRD:
00144       sharing = FILE_SHARE_WRITE;
00145       break;
00146     case _SH_COMPAT:
00147     case _SH_DENYNO:
00148       sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
00149       break;
00150     default:
00151       ERR("<-- -1 (Unhandled pmode 0x%x)\n", pmode);
00152       return -1;
00153   }
00154 
00155   if (oflag & ~(_O_BINARY | _O_TRUNC | _O_EXCL | _O_CREAT | _O_RDWR | _O_WRONLY | _O_NOINHERIT))
00156     WARN("unsupported oflag 0x%04x\n",oflag);
00157 
00158   sa.nLength              = sizeof( SECURITY_ATTRIBUTES );
00159   sa.lpSecurityDescriptor = NULL;
00160   sa.bInheritHandle       = (ioflag & _O_NOINHERIT) ? FALSE : TRUE;
00161 
00162   ret = (INT_PTR) CreateFileA(pszFile, ioflag, sharing, &sa, creation, FILE_ATTRIBUTE_NORMAL, NULL);
00163 
00164   /* TRACE("<-- %d\n", ret); */
00165 
00166   return ret;
00167 }
00168 
00169 static UINT sc_cb_read(INT_PTR hf, void *pv, UINT cb)
00170 {
00171   DWORD num_read;
00172   BOOL rslt;
00173 
00174   /* TRACE("(hf == %d, pv == ^%p, cb == %u)\n", hf, pv, cb); */
00175 
00176   rslt = ReadFile((HANDLE) hf, pv, cb, &num_read, NULL);
00177 
00178 
00179   /* eof and failure both give "-1" return */
00180   if ((! rslt) || ((cb > 0) && (num_read == 0))) {
00181     /* TRACE("<-- -1\n"); */
00182     return -1;
00183   }
00184 
00185   /* TRACE("<-- %lu\n", num_read); */
00186   return num_read;
00187 }
00188 
00189 static UINT sc_cb_write(INT_PTR hf, void *pv, UINT cb)
00190 {
00191   DWORD num_written;
00192   /* BOOL rv; */
00193 
00194   /* TRACE("(hf == %d, pv == ^%p, cb == %u)\n", hf, pv, cb); */
00195 
00196   if ( /* (rv = */ WriteFile((HANDLE) hf, pv, cb, &num_written, NULL) /* ) */
00197        && (num_written == cb)) {
00198     /* TRACE("<-- %lu\n", num_written); */
00199     return num_written;
00200   } else {
00201     /* TRACE("rv == %d, num_written == %lu, cb == %u\n", rv, num_written,cb); */
00202     /* TRACE("<-- -1\n"); */
00203     return -1;
00204   }
00205 }
00206 
00207 static int sc_cb_close(INT_PTR hf)
00208 {
00209   /* TRACE("(hf == %d)\n", hf); */
00210 
00211   if (CloseHandle((HANDLE) hf))
00212     return 0;
00213   else
00214     return -1;
00215 }
00216 
00217 static long sc_cb_lseek(INT_PTR hf, long dist, int seektype)
00218 {
00219   DWORD ret;
00220 
00221   /* TRACE("(hf == %d, dist == %ld, seektype == %d)\n", hf, dist, seektype); */
00222 
00223   if (seektype < 0 || seektype > 2)
00224     return -1;
00225 
00226   if (((ret = SetFilePointer((HANDLE) hf, dist, NULL, seektype)) != INVALID_SET_FILE_POINTER) || !GetLastError()) {
00227     /* TRACE("<-- %lu\n", ret); */
00228     return ret;
00229   } else {
00230     /* TRACE("<-- -1\n"); */
00231     return -1;
00232   }
00233 }
00234 
00235 #define SIZEOF_MYSTERIO (MAX_PATH*3)
00236 
00237 /* FDICopy callbacks */
00238 
00239 static INT_PTR sc_FNNOTIFY_A(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
00240 {
00241   FILE_IN_CABINET_INFO_A fici;
00242   PSC_HSC_A phsc;
00243   CABINET_INFO_A ci;
00244   FILEPATHS_A fp;
00245   UINT err;
00246 
00247   CHAR mysterio[SIZEOF_MYSTERIO]; /* how big? undocumented! probably 256... */
00248 
00249   memset(&(mysterio[0]), 0, SIZEOF_MYSTERIO);
00250 
00251   TRACE("(fdint == %d, pfdin == ^%p)\n", fdint, pfdin);
00252 
00253   if (pfdin && pfdin->pv && (*((void **) pfdin->pv) == (void *)SC_HSC_A_MAGIC))
00254     phsc = (PSC_HSC_A) pfdin->pv;
00255   else {
00256     ERR("pv %p is not an SC_HSC_A.\n", (pfdin) ? pfdin->pv : NULL);
00257     return -1;
00258   }
00259 
00260   switch (fdint) {
00261   case fdintCABINET_INFO:
00262     TRACE("Cabinet info notification\n");
00263     /* TRACE("  Cabinet name: %s\n", debugstr_a(pfdin->psz1));
00264     TRACE("  Cabinet disk: %s\n", debugstr_a(pfdin->psz2));
00265     TRACE("  Cabinet path: %s\n", debugstr_a(pfdin->psz3));
00266     TRACE("  Cabinet Set#: %d\n", pfdin->setID);
00267     TRACE("  Cabinet Cab#: %d\n", pfdin->iCabinet); */
00268     WARN("SPFILENOTIFY_CABINETINFO undocumented: guess implementation.\n");
00269     ci.CabinetFile = &(phsc->most_recent_cabinet_name[0]);
00270     ci.CabinetPath = pfdin->psz3;
00271     ci.DiskName = pfdin->psz2;
00272     ci.SetId = pfdin->setID;
00273     ci.CabinetNumber = pfdin->iCabinet;
00274     phsc->msghandler(phsc->context, SPFILENOTIFY_CABINETINFO, (UINT) &ci, 0);
00275     return 0;
00276   case fdintPARTIAL_FILE:
00277     TRACE("Partial file notification\n");
00278     /* TRACE("  Partial file name: %s\n", debugstr_a(pfdin->psz1)); */
00279     return 0;
00280   case fdintCOPY_FILE:
00281     TRACE("Copy file notification\n");
00282     TRACE("  File name: %s\n", debugstr_a(pfdin->psz1));
00283     /* TRACE("  File size: %ld\n", pfdin->cb);
00284     TRACE("  File date: %u\n", pfdin->date);
00285     TRACE("  File time: %u\n", pfdin->time);
00286     TRACE("  File attr: %u\n", pfdin->attribs); */
00287     fici.NameInCabinet = pfdin->psz1;
00288     fici.FileSize = pfdin->cb;
00289     fici.Win32Error = 0;
00290     fici.DosDate = pfdin->date;
00291     fici.DosTime = pfdin->time;
00292     fici.DosAttribs = pfdin->attribs;
00293     memset(&(fici.FullTargetName[0]), 0, MAX_PATH);
00294     err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEINCABINET,
00295                            (UINT) &fici, (UINT) pfdin->psz1);
00296     if (err == FILEOP_DOIT) {
00297       TRACE("  Callback specified filename: %s\n", debugstr_a(&(fici.FullTargetName[0])));
00298       if (!fici.FullTargetName[0]) {
00299         WARN("  Empty return string causing abort.\n");
00300         SetLastError(ERROR_PATH_NOT_FOUND);
00301         return -1;
00302       }
00303       return sc_cb_open(&(fici.FullTargetName[0]), _O_BINARY | _O_CREAT | _O_WRONLY,  _S_IREAD | _S_IWRITE);
00304     } else {
00305       TRACE("  Callback skipped file.\n");
00306       return 0;
00307     }
00308   case fdintCLOSE_FILE_INFO:
00309     TRACE("Close file notification\n");
00310     /* TRACE("  File name: %s\n", debugstr_a(pfdin->psz1));
00311     TRACE("  Exec file? %s\n", (pfdin->cb) ? "Yes" : "No");
00312     TRACE("  File hndl: %d\n", pfdin->hf); */
00313     fp.Source = &(phsc->most_recent_cabinet_name[0]);
00314     fp.Target = pfdin->psz1;
00315     fp.Win32Error = 0;
00316     fp.Flags = 0;
00317     /* the following should be a fixme -- but it occurs too many times */
00318     WARN("Should set file date/time/attribs (and execute files?)\n");
00319     err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEEXTRACTED, (UINT) &fp, 0);
00320     if (sc_cb_close(pfdin->hf))
00321       WARN("_close failed.\n");
00322     if (err) {
00323       SetLastError(err);
00324       return FALSE;
00325     } else
00326       return TRUE;
00327   case fdintNEXT_CABINET:
00328     TRACE("Next cabinet notification\n");
00329     /* TRACE("  Cabinet name: %s\n", debugstr_a(pfdin->psz1));
00330     TRACE("  Cabinet disk: %s\n", debugstr_a(pfdin->psz2));
00331     TRACE("  Cabinet path: %s\n", debugstr_a(pfdin->psz3));
00332     TRACE("  Cabinet Set#: %d\n", pfdin->setID);
00333     TRACE("  Cabinet Cab#: %d\n", pfdin->iCabinet); */
00334     ci.CabinetFile = pfdin->psz1;
00335     ci.CabinetPath = pfdin->psz3;
00336     ci.DiskName = pfdin->psz2;
00337     ci.SetId = pfdin->setID;
00338     ci.CabinetNumber = pfdin->iCabinet;
00339     /* remember the new cabinet name */
00340     strcpy(&(phsc->most_recent_cabinet_name[0]), pfdin->psz1);
00341     err = phsc->msghandler(phsc->context, SPFILENOTIFY_NEEDNEWCABINET, (UINT) &ci, (UINT) &(mysterio[0]));
00342     if (err) {
00343       SetLastError(err);
00344       return -1;
00345     } else {
00346       if (mysterio[0]) {
00347         /* some easy paranoia.  no such carefulness exists on the wide API IIRC */
00348         lstrcpynA(pfdin->psz3, &(mysterio[0]), SIZEOF_MYSTERIO);
00349       }
00350       return 0;
00351     }
00352   default:
00353     FIXME("Unknown notification type %d.\n", fdint);
00354     return 0;
00355   }
00356 }
00357 
00358 static INT_PTR sc_FNNOTIFY_W(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
00359 {
00360   FILE_IN_CABINET_INFO_W fici;
00361   PSC_HSC_W phsc;
00362   CABINET_INFO_W ci;
00363   FILEPATHS_W fp;
00364   UINT err;
00365   int len;
00366 
00367   WCHAR mysterio[SIZEOF_MYSTERIO]; /* how big? undocumented! */
00368   WCHAR buf[MAX_PATH], buf2[MAX_PATH];
00369   CHAR charbuf[MAX_PATH];
00370 
00371   memset(&(mysterio[0]), 0, SIZEOF_MYSTERIO * sizeof(WCHAR));
00372   memset(&(buf[0]), 0, MAX_PATH * sizeof(WCHAR));
00373   memset(&(buf2[0]), 0, MAX_PATH * sizeof(WCHAR));
00374   memset(&(charbuf[0]), 0, MAX_PATH);
00375 
00376   TRACE("(fdint == %d, pfdin == ^%p)\n", fdint, pfdin);
00377 
00378   if (pfdin && pfdin->pv && (*((void **) pfdin->pv) == (void *)SC_HSC_W_MAGIC))
00379     phsc = (PSC_HSC_W) pfdin->pv;
00380   else {
00381     ERR("pv %p is not an SC_HSC_W.\n", (pfdin) ? pfdin->pv : NULL);
00382     return -1;
00383   }
00384 
00385   switch (fdint) {
00386   case fdintCABINET_INFO:
00387     TRACE("Cabinet info notification\n");
00388     /* TRACE("  Cabinet name: %s\n", debugstr_a(pfdin->psz1));
00389     TRACE("  Cabinet disk: %s\n", debugstr_a(pfdin->psz2));
00390     TRACE("  Cabinet path: %s\n", debugstr_a(pfdin->psz3));
00391     TRACE("  Cabinet Set#: %d\n", pfdin->setID);
00392     TRACE("  Cabinet Cab#: %d\n", pfdin->iCabinet); */
00393     WARN("SPFILENOTIFY_CABINETINFO undocumented: guess implementation.\n");
00394     ci.CabinetFile = &(phsc->most_recent_cabinet_name[0]);
00395     len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz3, -1, &(buf[0]), MAX_PATH);
00396     if ((len > MAX_PATH) || (len <= 1))
00397       buf[0] = '\0';
00398     ci.CabinetPath = &(buf[0]);
00399     len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz2, -1, &(buf2[0]), MAX_PATH);
00400     if ((len > MAX_PATH) || (len <= 1))
00401       buf2[0] = '\0';
00402     ci.DiskName = &(buf2[0]);
00403     ci.SetId = pfdin->setID;
00404     ci.CabinetNumber = pfdin->iCabinet;
00405     phsc->msghandler(phsc->context, SPFILENOTIFY_CABINETINFO, (UINT) &ci, 0);
00406     return 0;
00407   case fdintPARTIAL_FILE:
00408     TRACE("Partial file notification\n");
00409     /* TRACE("  Partial file name: %s\n", debugstr_a(pfdin->psz1)); */
00410     return 0;
00411   case fdintCOPY_FILE:
00412     TRACE("Copy file notification\n");
00413     TRACE("  File name: %s\n", debugstr_a(pfdin->psz1));
00414     /* TRACE("  File size: %ld\n", pfdin->cb);
00415     TRACE("  File date: %u\n", pfdin->date);
00416     TRACE("  File time: %u\n", pfdin->time);
00417     TRACE("  File attr: %u\n", pfdin->attribs); */
00418     len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz1, -1, &(buf2[0]), MAX_PATH);
00419     if ((len > MAX_PATH) || (len <= 1))
00420       buf2[0] = '\0';
00421     fici.NameInCabinet = &(buf2[0]);
00422     fici.FileSize = pfdin->cb;
00423     fici.Win32Error = 0;
00424     fici.DosDate = pfdin->date;
00425     fici.DosTime = pfdin->time;
00426     fici.DosAttribs = pfdin->attribs;
00427     memset(&(fici.FullTargetName[0]), 0, MAX_PATH * sizeof(WCHAR));
00428     err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEINCABINET,
00429                            (UINT) &fici, (UINT) pfdin->psz1);
00430     if (err == FILEOP_DOIT) {
00431       TRACE("  Callback specified filename: %s\n", debugstr_w(&(fici.FullTargetName[0])));
00432       if (fici.FullTargetName[0]) {
00433         len = strlenW(&(fici.FullTargetName[0])) + 1;
00434         if ((len > MAX_PATH ) || (len <= 1))
00435           return 0;
00436         if (!WideCharToMultiByte(CP_ACP, 0, &(fici.FullTargetName[0]), len, &(charbuf[0]), MAX_PATH, 0, 0))
00437           return 0;
00438       } else {
00439         WARN("Empty buffer string caused abort.\n");
00440         SetLastError(ERROR_PATH_NOT_FOUND);
00441         return -1;
00442       }
00443       return sc_cb_open(&(charbuf[0]), _O_BINARY | _O_CREAT | _O_WRONLY,  _S_IREAD | _S_IWRITE);
00444     } else {
00445       TRACE("  Callback skipped file.\n");
00446       return 0;
00447     }
00448   case fdintCLOSE_FILE_INFO:
00449     TRACE("Close file notification\n");
00450     /* TRACE("  File name: %s\n", debugstr_a(pfdin->psz1));
00451     TRACE("  Exec file? %s\n", (pfdin->cb) ? "Yes" : "No");
00452     TRACE("  File hndl: %d\n", pfdin->hf); */
00453     fp.Source = &(phsc->most_recent_cabinet_name[0]);
00454     len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz1, -1, &(buf[0]), MAX_PATH);
00455     if ((len > MAX_PATH) || (len <= 1))
00456       buf[0] = '\0';
00457     fp.Target = &(buf[0]);
00458     fp.Win32Error = 0;
00459     fp.Flags = 0;
00460     /* a valid fixme -- but occurs too many times */
00461     /* FIXME("Should set file date/time/attribs (and execute files?)\n"); */
00462     err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEEXTRACTED, (UINT) &fp, 0);
00463     if (sc_cb_close(pfdin->hf))
00464       WARN("_close failed.\n");
00465     if (err) {
00466       SetLastError(err);
00467       return FALSE;
00468     } else
00469       return TRUE;
00470   case fdintNEXT_CABINET:
00471     TRACE("Next cabinet notification\n");
00472     /* TRACE("  Cabinet name: %s\n", debugstr_a(pfdin->psz1));
00473     TRACE("  Cabinet disk: %s\n", debugstr_a(pfdin->psz2));
00474     TRACE("  Cabinet path: %s\n", debugstr_a(pfdin->psz3));
00475     TRACE("  Cabinet Set#: %d\n", pfdin->setID);
00476     TRACE("  Cabinet Cab#: %d\n", pfdin->iCabinet); */
00477     /* remember the new cabinet name */
00478     len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz1, -1, &(phsc->most_recent_cabinet_name[0]), MAX_PATH);
00479     if ((len > MAX_PATH) || (len <= 1))
00480       phsc->most_recent_cabinet_name[0] = '\0';
00481     ci.CabinetFile = &(phsc->most_recent_cabinet_name[0]);
00482     len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz3, -1, &(buf[0]), MAX_PATH);
00483     if ((len > MAX_PATH) || (len <= 1))
00484       buf[0] = '\0';
00485     ci.CabinetPath = &(buf[0]);
00486     len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz2, -1, &(buf2[0]), MAX_PATH);
00487     if ((len > MAX_PATH) || (len <= 1))
00488       buf2[0] = '\0';
00489     ci.DiskName = &(buf2[0]);
00490     ci.SetId = pfdin->setID;
00491     ci.CabinetNumber = pfdin->iCabinet;
00492     err = phsc->msghandler(phsc->context, SPFILENOTIFY_NEEDNEWCABINET, (UINT) &ci, (UINT) &(mysterio[0]));
00493     if (err) {
00494       SetLastError(err);
00495       return -1;
00496     } else {
00497       if (mysterio[0]) {
00498         len = strlenW(&(mysterio[0])) + 1;
00499         if ((len > 255) || (len <= 1))
00500           return 0;
00501         if (!WideCharToMultiByte(CP_ACP, 0, &(mysterio[0]), len, pfdin->psz3, 255, 0, 0))
00502           return 0;
00503       }
00504       return 0;
00505     }
00506   default:
00507     FIXME("Unknown notification type %d.\n", fdint);
00508     return 0;
00509   }
00510 }
00511 
00512 /***********************************************************************
00513  *      SetupIterateCabinetA (SETUPAPI.@)
00514  */
00515 BOOL WINAPI SetupIterateCabinetA(PCSTR CabinetFile, DWORD Reserved,
00516                                  PSP_FILE_CALLBACK_A MsgHandler, PVOID Context)
00517 {
00518 
00519   SC_HSC_A my_hsc;
00520   ERF erf;
00521   CHAR pszCabinet[MAX_PATH], pszCabPath[MAX_PATH], *p = NULL;
00522   DWORD fpnsize;
00523   BOOL ret;
00524 
00525 
00526   TRACE("(CabinetFile == %s, Reserved == %u, MsgHandler == ^%p, Context == ^%p)\n",
00527         debugstr_a(CabinetFile), Reserved, MsgHandler, Context);
00528 
00529   if (! LoadCABINETDll()) 
00530     return FALSE;
00531 
00532   if (!CabinetFile)
00533   {
00534     SetLastError(ERROR_INVALID_PARAMETER);
00535     return FALSE;
00536   }
00537 
00538   memset(&my_hsc, 0, sizeof(SC_HSC_A));
00539   pszCabinet[0] = '\0';
00540   pszCabPath[0] = '\0';
00541 
00542   fpnsize = strlen(CabinetFile);
00543   if (fpnsize >= MAX_PATH) {
00544     SetLastError(ERROR_BAD_PATHNAME);
00545     return FALSE;
00546   }
00547 
00548   fpnsize = GetFullPathNameA(CabinetFile, MAX_PATH, &(pszCabPath[0]), &p);
00549   if (fpnsize > MAX_PATH) {
00550     SetLastError(ERROR_BAD_PATHNAME);
00551     return FALSE;
00552   }
00553 
00554   if (p) {
00555     strcpy(pszCabinet, p);
00556     *p = '\0';
00557   } else {
00558     strcpy(pszCabinet, CabinetFile);
00559     pszCabPath[0] = '\0';
00560   }
00561 
00562   TRACE("path: %s, cabfile: %s\n", debugstr_a(pszCabPath), debugstr_a(pszCabinet));
00563 
00564   /* remember the cabinet name */
00565   strcpy(&(my_hsc.most_recent_cabinet_name[0]), pszCabinet);
00566 
00567   my_hsc.magic = SC_HSC_A_MAGIC;
00568   my_hsc.msghandler = MsgHandler;
00569   my_hsc.context = Context;
00570   my_hsc.hfdi = sc_FDICreate( sc_cb_alloc, sc_cb_free, sc_cb_open, sc_cb_read,
00571                            sc_cb_write, sc_cb_close, sc_cb_lseek, cpuUNKNOWN, &erf );
00572 
00573   if (!my_hsc.hfdi) return FALSE;
00574 
00575   ret = ( sc_FDICopy(my_hsc.hfdi, pszCabinet, pszCabPath,
00576                      0, sc_FNNOTIFY_A, NULL, &my_hsc)     ) ? TRUE : FALSE;
00577 
00578   sc_FDIDestroy(my_hsc.hfdi);
00579   return ret;
00580 }
00581 
00582 
00583 /***********************************************************************
00584  *      SetupIterateCabinetW (SETUPAPI.@)
00585  */
00586 BOOL WINAPI SetupIterateCabinetW(PCWSTR CabinetFile, DWORD Reserved,
00587                                  PSP_FILE_CALLBACK_W MsgHandler, PVOID Context)
00588 {
00589   CHAR pszCabinet[MAX_PATH], pszCabPath[MAX_PATH];
00590   UINT len;
00591   SC_HSC_W my_hsc;
00592   ERF erf;
00593   WCHAR pszCabPathW[MAX_PATH], *p = NULL;
00594   DWORD fpnsize;
00595   BOOL ret;
00596 
00597   TRACE("(CabinetFile == %s, Reserved == %u, MsgHandler == ^%p, Context == ^%p)\n",
00598         debugstr_w(CabinetFile), Reserved, MsgHandler, Context);
00599 
00600   if (!LoadCABINETDll())
00601     return FALSE;
00602 
00603   if (!CabinetFile)
00604   {
00605     SetLastError(ERROR_INVALID_PARAMETER);
00606     return FALSE;
00607   }
00608 
00609   memset(&my_hsc, 0, sizeof(SC_HSC_W));
00610 
00611   fpnsize = GetFullPathNameW(CabinetFile, MAX_PATH, pszCabPathW, &p);
00612   if (fpnsize > MAX_PATH) {
00613     SetLastError(ERROR_BAD_PATHNAME);
00614     return FALSE;
00615   }
00616 
00617   if (p) {
00618     strcpyW(my_hsc.most_recent_cabinet_name, p);
00619     *p = 0;
00620     len = WideCharToMultiByte(CP_ACP, 0, pszCabPathW, -1, pszCabPath,
00621                 MAX_PATH, 0, 0);
00622     if (!len) return FALSE;
00623   } else {
00624     strcpyW(my_hsc.most_recent_cabinet_name, CabinetFile);
00625     pszCabPath[0] = '\0';
00626   }
00627 
00628   len = WideCharToMultiByte(CP_ACP, 0, my_hsc.most_recent_cabinet_name, -1,
00629                 pszCabinet, MAX_PATH, 0, 0);
00630   if (!len) return FALSE;
00631 
00632   TRACE("path: %s, cabfile: %s\n",
00633     debugstr_a(pszCabPath), debugstr_a(pszCabinet));
00634 
00635   my_hsc.magic = SC_HSC_W_MAGIC;
00636   my_hsc.msghandler = MsgHandler;
00637   my_hsc.context = Context;
00638   my_hsc.hfdi = sc_FDICreate( sc_cb_alloc, sc_cb_free, sc_cb_open, sc_cb_read,
00639                               sc_cb_write, sc_cb_close, sc_cb_lseek, cpuUNKNOWN, &erf );
00640 
00641   if (!my_hsc.hfdi) return FALSE;
00642 
00643   ret = ( sc_FDICopy(my_hsc.hfdi, pszCabinet, pszCabPath,
00644                      0, sc_FNNOTIFY_W, NULL, &my_hsc)     ) ? TRUE : FALSE;
00645 
00646   sc_FDIDestroy(my_hsc.hfdi);
00647   return ret;
00648 }
00649 
00650 
00651 /***********************************************************************
00652  * DllMain
00653  *
00654  * PARAMS
00655  *     hinstDLL    [I] handle to the DLL's instance
00656  *     fdwReason   [I]
00657  *     lpvReserved [I] reserved, must be NULL
00658  *
00659  * RETURNS
00660  *     Success: TRUE
00661  *     Failure: FALSE
00662  */
00663 
00664 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
00665 {
00666     switch (fdwReason) {
00667     case DLL_PROCESS_ATTACH:
00668         DisableThreadLibraryCalls(hinstDLL);
00669         OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
00670         if (!GetVersionExW(&OsVersionInfo))
00671             return FALSE;
00672         hInstance = (HINSTANCE)hinstDLL;
00673         break;
00674     case DLL_PROCESS_DETACH:
00675         UnloadCABINETDll();
00676         break;
00677     }
00678 
00679     return TRUE;
00680 }

Generated on Sat May 26 2012 04:24:50 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.