[PATCH 1/5] setupapi: Implement SetupIterateCabinetW() on top of SetupIterateCabinetA().
Zebediah Figura
z.figura12 at gmail.com
Thu Mar 4 20:08:13 CST 2021
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/setupapi/setupcab.c | 318 ++++++++++++---------------------------
1 file changed, 98 insertions(+), 220 deletions(-)
diff --git a/dlls/setupapi/setupcab.c b/dlls/setupapi/setupcab.c
index b9783b81356..55d0fe6f64c 100644
--- a/dlls/setupapi/setupcab.c
+++ b/dlls/setupapi/setupcab.c
@@ -84,16 +84,6 @@ typedef struct {
CHAR most_recent_target[MAX_PATH];
} SC_HSC_A, *PSC_HSC_A;
-#define SC_HSC_W_MAGIC 0x0CABFEED
-typedef struct {
- UINT magic;
- HFDI hfdi;
- PSP_FILE_CALLBACK_W msghandler;
- PVOID context;
- WCHAR most_recent_cabinet_name[MAX_PATH];
- WCHAR most_recent_target[MAX_PATH];
-} SC_HSC_W, *PSC_HSC_W;
-
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
static BOOL LoadCABINETDll(void)
@@ -386,158 +376,6 @@ static INT_PTR CDECL sc_FNNOTIFY_A(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION p
}
}
-static INT_PTR CDECL 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, SIZEOF_MYSTERIO * sizeof(WCHAR));
- memset(buf, 0, MAX_PATH * sizeof(WCHAR));
- memset(buf2, 0, MAX_PATH * sizeof(WCHAR));
- memset(charbuf, 0, MAX_PATH);
-
- TRACE("(fdint == %d, pfdin == ^%p)\n", fdint, pfdin);
-
- if (pfdin && pfdin->pv && (((PSC_HSC_W) pfdin->pv)->magic == SC_HSC_W_MAGIC))
- phsc = 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;
- len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz3, -1, buf, MAX_PATH);
- if ((len > MAX_PATH) || (len <= 1))
- buf[0] = '\0';
- ci.CabinetPath = buf;
- len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz2, -1, buf2, MAX_PATH);
- if ((len > MAX_PATH) || (len <= 1))
- buf2[0] = '\0';
- ci.DiskName = buf2;
- ci.SetId = pfdin->setID;
- ci.CabinetNumber = pfdin->iCabinet;
- phsc->msghandler(phsc->context, SPFILENOTIFY_CABINETINFO, (UINT_PTR)&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, MAX_PATH);
- if ((len > MAX_PATH) || (len <= 1))
- buf2[0] = '\0';
- fici.NameInCabinet = buf2;
- fici.FileSize = pfdin->cb;
- fici.Win32Error = 0;
- fici.DosDate = pfdin->date;
- fici.DosTime = pfdin->time;
- fici.DosAttribs = pfdin->attribs;
- memset(fici.FullTargetName, 0, MAX_PATH * sizeof(WCHAR));
- err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEINCABINET,
- (UINT_PTR)&fici, (UINT_PTR)pfdin->psz1);
- if (err == FILEOP_DOIT) {
- TRACE(" Callback specified filename: %s\n", debugstr_w(fici.FullTargetName));
- if (fici.FullTargetName[0]) {
- len = lstrlenW(fici.FullTargetName) + 1;
- if ((len > MAX_PATH ) || (len <= 1))
- return 0;
- if (!WideCharToMultiByte(CP_ACP, 0, fici.FullTargetName, len, charbuf, MAX_PATH, 0, 0))
- return 0;
- } else {
- WARN("Empty buffer string caused abort.\n");
- SetLastError(ERROR_PATH_NOT_FOUND);
- return -1;
- }
- lstrcpyW( phsc->most_recent_target, fici.FullTargetName );
- return sc_cb_open(charbuf, _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;
- fp.Target = phsc->most_recent_target;
- 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"); */
- if (sc_cb_close(pfdin->hf))
- WARN("_close failed.\n");
- err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEEXTRACTED, (UINT_PTR)&fp, 0);
- 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, MAX_PATH);
- if ((len > MAX_PATH) || (len <= 1))
- phsc->most_recent_cabinet_name[0] = '\0';
- ci.CabinetFile = phsc->most_recent_cabinet_name;
- len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz3, -1, buf, MAX_PATH);
- if ((len > MAX_PATH) || (len <= 1))
- buf[0] = '\0';
- ci.CabinetPath = buf;
- len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz2, -1, buf2, MAX_PATH);
- if ((len > MAX_PATH) || (len <= 1))
- buf2[0] = '\0';
- ci.DiskName = buf2;
- ci.SetId = pfdin->setID;
- ci.CabinetNumber = pfdin->iCabinet;
- err = phsc->msghandler(phsc->context, SPFILENOTIFY_NEEDNEWCABINET, (UINT_PTR)&ci, (UINT_PTR)mysterio);
- if (err) {
- SetLastError(err);
- return -1;
- } else {
- if (mysterio[0]) {
- len = lstrlenW(mysterio) + 1;
- if ((len > 255) || (len <= 1))
- return 0;
- if (!WideCharToMultiByte(CP_ACP, 0, mysterio, len, pfdin->psz3, 255, 0, 0))
- return 0;
- }
- return 0;
- }
- default:
- FIXME("Unknown notification type %d.\n", fdint);
- return 0;
- }
-}
-
/***********************************************************************
* SetupIterateCabinetA (SETUPAPI.@)
*/
@@ -602,72 +440,112 @@ BOOL WINAPI SetupIterateCabinetA(PCSTR CabinetFile, DWORD Reserved,
return ret;
}
+struct iterate_wtoa_ctx
+{
+ PSP_FILE_CALLBACK_A orig_cb;
+ void *orig_ctx;
+};
+
+static UINT WINAPI iterate_wtoa_cb(void *pctx, UINT message, UINT_PTR param1, UINT_PTR param2)
+{
+ struct iterate_wtoa_ctx *ctx = pctx;
+
+ switch (message)
+ {
+ case SPFILENOTIFY_CABINETINFO:
+ case SPFILENOTIFY_NEEDNEWCABINET:
+ {
+ const CABINET_INFO_A *infoA = (const CABINET_INFO_A *)param1;
+ WCHAR pathW[MAX_PATH], fileW[MAX_PATH], diskW[MAX_PATH];
+ CABINET_INFO_W infoW =
+ {
+ .CabinetPath = pathW,
+ .CabinetFile = fileW,
+ .DiskName = diskW,
+ .SetId = infoA->SetId,
+ .CabinetNumber = infoA->CabinetNumber,
+ };
+
+ MultiByteToWideChar(CP_ACP, 0, infoA->CabinetPath, -1, pathW, ARRAY_SIZE(pathW));
+ MultiByteToWideChar(CP_ACP, 0, infoA->CabinetFile, -1, fileW, ARRAY_SIZE(fileW));
+ MultiByteToWideChar(CP_ACP, 0, infoA->DiskName, -1, diskW, ARRAY_SIZE(diskW));
+
+ if (message == SPFILENOTIFY_CABINETINFO)
+ return ctx->orig_cb(ctx->orig_ctx, message, (UINT_PTR)&infoW, 0);
+ else
+ {
+ char *newpathA = (char *)param2;
+ WCHAR newpathW[MAX_PATH] = {0};
+ BOOL ret = ctx->orig_cb(ctx->orig_ctx, message, (UINT_PTR)&infoW, (UINT_PTR)newpathW);
+
+ WideCharToMultiByte(CP_ACP, 0, newpathW, -1, newpathA, MAX_PATH, NULL, NULL);
+ return ret;
+ }
+ }
+ case SPFILENOTIFY_FILEINCABINET:
+ {
+ FILE_IN_CABINET_INFO_A *infoA = (FILE_IN_CABINET_INFO_A *)param1;
+ const char *cabA = (const char *)param2;
+ WCHAR cabW[MAX_PATH], fileW[MAX_PATH];
+ FILE_IN_CABINET_INFO_W infoW =
+ {
+ .NameInCabinet = fileW,
+ .FileSize = infoA->FileSize,
+ .Win32Error = infoA->Win32Error,
+ .DosDate = infoA->DosDate,
+ .DosTime = infoA->DosTime,
+ .DosAttribs = infoA->DosAttribs,
+ };
+ BOOL ret;
+
+ MultiByteToWideChar(CP_ACP, 0, infoA->NameInCabinet, -1, fileW, ARRAY_SIZE(fileW));
+ MultiByteToWideChar(CP_ACP, 0, cabA, -1, cabW, ARRAY_SIZE(cabW));
+
+ ret = ctx->orig_cb(ctx->orig_ctx, message, (UINT_PTR)&infoW, (UINT_PTR)cabW);
+
+ WideCharToMultiByte(CP_ACP, 0, infoW.FullTargetName, -1, infoA->FullTargetName,
+ ARRAY_SIZE(infoA->FullTargetName), NULL, NULL);
+
+ return ret;
+ }
+ case SPFILENOTIFY_FILEEXTRACTED:
+ {
+ const FILEPATHS_A *pathsA = (const FILEPATHS_A *)param1;
+ WCHAR targetW[MAX_PATH], sourceW[MAX_PATH];
+ FILEPATHS_W pathsW =
+ {
+ .Target = targetW,
+ .Source = sourceW,
+ .Win32Error = pathsA->Win32Error,
+ .Flags = pathsA->Flags,
+ };
+
+ MultiByteToWideChar(CP_ACP, 0, pathsA->Target, -1, targetW, ARRAY_SIZE(targetW));
+ MultiByteToWideChar(CP_ACP, 0, pathsA->Source, -1, sourceW, ARRAY_SIZE(sourceW));
+
+ return ctx->orig_cb(ctx->orig_ctx, message, (UINT_PTR)&pathsW, 0);
+ }
+ default:
+ FIXME("Unexpected callback %#x.\n", message);
+ return FALSE;
+ }
+}
/***********************************************************************
- * SetupIterateCabinetW (SETUPAPI.@)
+ * SetupIterateCabinetW (SETUPAPI.@)
*/
-BOOL WINAPI SetupIterateCabinetW(PCWSTR CabinetFile, DWORD Reserved,
- PSP_FILE_CALLBACK_W MsgHandler, PVOID Context)
+BOOL WINAPI SetupIterateCabinetW(const WCHAR *fileW, DWORD reserved,
+ PSP_FILE_CALLBACK_W handler, void *context)
{
- CHAR pszCabinet[MAX_PATH], pszCabPath[MAX_PATH];
- UINT len;
- SC_HSC_W my_hsc;
- ERF erf;
- WCHAR pszCabPathW[MAX_PATH], *p = NULL;
- DWORD fpnsize;
- BOOL ret;
-
- TRACE("(CabinetFile == %s, Reserved == %u, MsgHandler == ^%p, Context == ^%p)\n",
- debugstr_w(CabinetFile), Reserved, MsgHandler, Context);
-
- if (!LoadCABINETDll())
- return FALSE;
-
- if (!CabinetFile)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
+ struct iterate_wtoa_ctx ctx = {handler, context};
+ char fileA[MAX_PATH];
- fpnsize = GetFullPathNameW(CabinetFile, MAX_PATH, pszCabPathW, &p);
- if (fpnsize > MAX_PATH) {
- SetLastError(ERROR_BAD_PATHNAME);
- return FALSE;
- }
+ if (!WideCharToMultiByte(CP_ACP, 0, fileW, -1, fileA, ARRAY_SIZE(fileA), NULL, NULL))
+ return FALSE;
- if (p) {
- lstrcpyW(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 {
- lstrcpyW(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);
-
- sc_FDIDestroy(my_hsc.hfdi);
- return ret;
+ return SetupIterateCabinetA(fileA, reserved, iterate_wtoa_cb, &ctx);
}
-
/***********************************************************************
* DllMain
*
--
2.20.1
More information about the wine-devel
mailing list