Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensetupcab.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
1.7.6.1
|