📄 setupcab.c
字号:
ci.SetId = pfdin->setID;
ci.CabinetNumber = pfdin->iCabinet;
/* remember the new cabinet name */
strcpy(&(phsc->most_recent_cabinet_name[0]), pfdin->psz1);
err = phsc->msghandler(phsc->context, SPFILENOTIFY_NEEDNEWCABINET, (UINT) &ci, (UINT) &(mysterio[0]));
if (err) {
SetLastError(err);
return -1;
} else {
if (mysterio[0]) {
/* some easy paranoia. no such carefulness exists on the wide API IIRC */
lstrcpynA(pfdin->psz3, &(mysterio[0]), SIZEOF_MYSTERIO);
}
return 0;
}
default:
FIXME("Unknown notification type %d.\n", fdint);
return 0;
}
}
static INT_PTR sc_FNNOTIFY_W(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
{
FILE_IN_CABINET_INFO_W fici;
PSC_HSC_W phsc;
CABINET_INFO_W ci;
FILEPATHS_W fp;
UINT err;
int len;
WCHAR mysterio[SIZEOF_MYSTERIO]; /* how big? undocumented! */
WCHAR buf[MAX_PATH], buf2[MAX_PATH];
CHAR charbuf[MAX_PATH];
memset(&(mysterio[0]), 0, SIZEOF_MYSTERIO * sizeof(WCHAR));
memset(&(buf[0]), 0, MAX_PATH * sizeof(WCHAR));
memset(&(buf2[0]), 0, MAX_PATH * sizeof(WCHAR));
memset(&(charbuf[0]), 0, MAX_PATH);
TRACE("(fdint == %d, pfdin == ^%p)\n", fdint, pfdin);
if (pfdin && pfdin->pv && (*((void **) pfdin->pv) == (void *)SC_HSC_W_MAGIC))
phsc = (PSC_HSC_W) pfdin->pv;
else {
ERR("pv %p is not an SC_HSC_W.\n", (pfdin) ? pfdin->pv : NULL);
return -1;
}
switch (fdint) {
case fdintCABINET_INFO:
TRACE("Cabinet info notification\n");
/* TRACE(" Cabinet name: %s\n", debugstr_a(pfdin->psz1));
TRACE(" Cabinet disk: %s\n", debugstr_a(pfdin->psz2));
TRACE(" Cabinet path: %s\n", debugstr_a(pfdin->psz3));
TRACE(" Cabinet Set#: %d\n", pfdin->setID);
TRACE(" Cabinet Cab#: %d\n", pfdin->iCabinet); */
WARN("SPFILENOTIFY_CABINETINFO undocumented: guess implementation.\n");
ci.CabinetFile = &(phsc->most_recent_cabinet_name[0]);
len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz3, -1, &(buf[0]), MAX_PATH);
if ((len > MAX_PATH) || (len <= 1))
buf[0] = '\0';
ci.CabinetPath = &(buf[0]);
len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz2, -1, &(buf2[0]), MAX_PATH);
if ((len > MAX_PATH) || (len <= 1))
buf2[0] = '\0';
ci.DiskName = &(buf2[0]);
ci.SetId = pfdin->setID;
ci.CabinetNumber = pfdin->iCabinet;
phsc->msghandler(phsc->context, SPFILENOTIFY_CABINETINFO, (UINT) &ci, 0);
return 0;
case fdintPARTIAL_FILE:
TRACE("Partial file notification\n");
/* TRACE(" Partial file name: %s\n", debugstr_a(pfdin->psz1)); */
return 0;
case fdintCOPY_FILE:
TRACE("Copy file notification\n");
TRACE(" File name: %s\n", debugstr_a(pfdin->psz1));
/* TRACE(" File size: %ld\n", pfdin->cb);
TRACE(" File date: %u\n", pfdin->date);
TRACE(" File time: %u\n", pfdin->time);
TRACE(" File attr: %u\n", pfdin->attribs); */
len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz1, -1, &(buf2[0]), MAX_PATH);
if ((len > MAX_PATH) || (len <= 1))
buf2[0] = '\0';
fici.NameInCabinet = &(buf2[0]);
fici.FileSize = pfdin->cb;
fici.Win32Error = 0;
fici.DosDate = pfdin->date;
fici.DosTime = pfdin->time;
fici.DosAttribs = pfdin->attribs;
memset(&(fici.FullTargetName[0]), 0, MAX_PATH * sizeof(WCHAR));
err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEINCABINET,
(UINT) &fici, (UINT) pfdin->psz1);
if (err == FILEOP_DOIT) {
TRACE(" Callback specified filename: %s\n", debugstr_w(&(fici.FullTargetName[0])));
if (fici.FullTargetName[0]) {
len = strlenW(&(fici.FullTargetName[0])) + 1;
if ((len > MAX_PATH ) || (len <= 1))
return 0;
if (!WideCharToMultiByte(CP_ACP, 0, &(fici.FullTargetName[0]), len, &(charbuf[0]), MAX_PATH, 0, 0))
return 0;
} else {
WARN("Empty buffer string caused abort.\n");
SetLastError(ERROR_PATH_NOT_FOUND);
return -1;
}
return sc_cb_open(&(charbuf[0]), _O_BINARY | _O_CREAT | _O_WRONLY, _S_IREAD | _S_IWRITE);
} else {
TRACE(" Callback skipped file.\n");
return 0;
}
case fdintCLOSE_FILE_INFO:
TRACE("Close file notification\n");
/* TRACE(" File name: %s\n", debugstr_a(pfdin->psz1));
TRACE(" Exec file? %s\n", (pfdin->cb) ? "Yes" : "No");
TRACE(" File hndl: %d\n", pfdin->hf); */
fp.Source = &(phsc->most_recent_cabinet_name[0]);
len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz1, -1, &(buf[0]), MAX_PATH);
if ((len > MAX_PATH) || (len <= 1))
buf[0] = '\0';
fp.Target = &(buf[0]);
fp.Win32Error = 0;
fp.Flags = 0;
/* a valid fixme -- but occurs too many times */
/* FIXME("Should set file date/time/attribs (and execute files?)\n"); */
err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEEXTRACTED, (UINT) &fp, 0);
if (sc_cb_close(pfdin->hf))
WARN("_close failed.\n");
if (err) {
SetLastError(err);
return FALSE;
} else
return TRUE;
case fdintNEXT_CABINET:
TRACE("Next cabinet notification\n");
/* TRACE(" Cabinet name: %s\n", debugstr_a(pfdin->psz1));
TRACE(" Cabinet disk: %s\n", debugstr_a(pfdin->psz2));
TRACE(" Cabinet path: %s\n", debugstr_a(pfdin->psz3));
TRACE(" Cabinet Set#: %d\n", pfdin->setID);
TRACE(" Cabinet Cab#: %d\n", pfdin->iCabinet); */
/* remember the new cabinet name */
len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz1, -1, &(phsc->most_recent_cabinet_name[0]), MAX_PATH);
if ((len > MAX_PATH) || (len <= 1))
phsc->most_recent_cabinet_name[0] = '\0';
ci.CabinetFile = &(phsc->most_recent_cabinet_name[0]);
len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz3, -1, &(buf[0]), MAX_PATH);
if ((len > MAX_PATH) || (len <= 1))
buf[0] = '\0';
ci.CabinetPath = &(buf[0]);
len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz2, -1, &(buf2[0]), MAX_PATH);
if ((len > MAX_PATH) || (len <= 1))
buf2[0] = '\0';
ci.DiskName = &(buf2[0]);
ci.SetId = pfdin->setID;
ci.CabinetNumber = pfdin->iCabinet;
err = phsc->msghandler(phsc->context, SPFILENOTIFY_NEEDNEWCABINET, (UINT) &ci, (UINT) &(mysterio[0]));
if (err) {
SetLastError(err);
return -1;
} else {
if (mysterio[0]) {
len = strlenW(&(mysterio[0])) + 1;
if ((len > 255) || (len <= 1))
return 0;
if (!WideCharToMultiByte(CP_ACP, 0, &(mysterio[0]), len, pfdin->psz3, 255, 0, 0))
return 0;
}
return 0;
}
default:
FIXME("Unknown notification type %d.\n", fdint);
return 0;
}
}
/***********************************************************************
* SetupIterateCabinetA (SETUPAPI.@)
*/
BOOL WINAPI SetupIterateCabinetA(PCSTR CabinetFile, DWORD Reserved,
PSP_FILE_CALLBACK_A MsgHandler, PVOID Context)
{
SC_HSC_A my_hsc;
ERF erf;
CHAR pszCabinet[MAX_PATH], pszCabPath[MAX_PATH], *p;
DWORD fpnsize;
BOOL ret;
TRACE("(CabinetFile == %s, Reserved == %lu, MsgHandler == ^%p, Context == ^%p)\n",
debugstr_a(CabinetFile), Reserved, MsgHandler, Context);
if (! LoadCABINETDll())
return FALSE;
memset(&my_hsc, 0, sizeof(SC_HSC_A));
pszCabinet[0] = '\0';
pszCabPath[0] = '\0';
fpnsize = strlen(CabinetFile);
if (fpnsize >= MAX_PATH) {
SetLastError(ERROR_BAD_PATHNAME);
return FALSE;
}
fpnsize = GetFullPathNameA(CabinetFile, MAX_PATH, &(pszCabPath[0]), &p);
if (fpnsize > MAX_PATH) {
SetLastError(ERROR_BAD_PATHNAME);
return FALSE;
}
if (p) {
strcpy(pszCabinet, p);
*p = '\0';
} else {
strcpy(pszCabinet, CabinetFile);
pszCabPath[0] = '\0';
}
TRACE("path: %s, cabfile: %s\n", debugstr_a(pszCabPath), debugstr_a(pszCabinet));
/* remember the cabinet name */
strcpy(&(my_hsc.most_recent_cabinet_name[0]), pszCabinet);
my_hsc.magic = SC_HSC_A_MAGIC;
my_hsc.msghandler = MsgHandler;
my_hsc.context = Context;
my_hsc.hfdi = sc_FDICreate( sc_cb_alloc, sc_cb_free, sc_cb_open, sc_cb_read,
sc_cb_write, sc_cb_close, sc_cb_lseek, cpuUNKNOWN, &erf );
if (!my_hsc.hfdi) return FALSE;
ret = ( sc_FDICopy(my_hsc.hfdi, pszCabinet, pszCabPath,
0, sc_FNNOTIFY_A, NULL, &my_hsc) ) ? TRUE : FALSE;
sc_FDIDestroy(my_hsc.hfdi);
return ret;
}
/***********************************************************************
* SetupIterateCabinetW (SETUPAPI.@)
*/
BOOL WINAPI SetupIterateCabinetW(PCWSTR CabinetFile, DWORD Reserved,
PSP_FILE_CALLBACK_W MsgHandler, PVOID Context)
{
CHAR pszCabinet[MAX_PATH], pszCabPath[MAX_PATH];
UINT len;
SC_HSC_W my_hsc;
ERF erf;
WCHAR pszCabPathW[MAX_PATH], *p;
DWORD fpnsize;
BOOL ret;
TRACE("(CabinetFile == %s, Reserved == %lu, MsgHandler == ^%p, Context == ^%p)\n",
debugstr_w(CabinetFile), Reserved, MsgHandler, Context);
if (!LoadCABINETDll())
return FALSE;
if (!CabinetFile) return FALSE;
memset(&my_hsc, 0, sizeof(SC_HSC_W));
fpnsize = GetFullPathNameW(CabinetFile, MAX_PATH, pszCabPathW, &p);
if (fpnsize > MAX_PATH) {
SetLastError(ERROR_BAD_PATHNAME);
return FALSE;
}
if (p) {
strcpyW(my_hsc.most_recent_cabinet_name, p);
*p = 0;
len = WideCharToMultiByte(CP_ACP, 0, pszCabPathW, -1, pszCabPath,
MAX_PATH, 0, 0);
if (!len) return FALSE;
} else {
strcpyW(my_hsc.most_recent_cabinet_name, CabinetFile);
pszCabPath[0] = '\0';
}
len = WideCharToMultiByte(CP_ACP, 0, my_hsc.most_recent_cabinet_name, -1,
pszCabinet, MAX_PATH, 0, 0);
if (!len) return FALSE;
TRACE("path: %s, cabfile: %s\n",
debugstr_a(pszCabPath), debugstr_a(pszCabinet));
my_hsc.magic = SC_HSC_W_MAGIC;
my_hsc.msghandler = MsgHandler;
my_hsc.context = Context;
my_hsc.hfdi = sc_FDICreate( sc_cb_alloc, sc_cb_free, sc_cb_open, sc_cb_read,
sc_cb_write, sc_cb_close, sc_cb_lseek, cpuUNKNOWN, &erf );
if (!my_hsc.hfdi) return FALSE;
ret = ( sc_FDICopy(my_hsc.hfdi, pszCabinet, pszCabPath,
0, sc_FNNOTIFY_W, NULL, &my_hsc) ) ? TRUE : FALSE;
sc_FDIDestroy(my_hsc.hfdi);
return ret;
}
/***********************************************************************
* DllMain
*
* PARAMS
* hinstDLL [I] handle to the DLL's instance
* fdwReason [I]
* lpvReserved [I] reserved, must be NULL
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
if (!GetVersionExW(&OsVersionInfo))
return FALSE;
hInstance = (HINSTANCE)hinstDLL;
break;
case DLL_PROCESS_DETACH:
UnloadCABINETDll();
break;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -