2 * SetupAPI virtual copy operations
4 * Copyright 2001 Andreas Mohr
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * FIXME: we now rely on builtin setupapi.dll for dialog resources.
21 * This is bad ! We ought to have 16bit resource handling working.
35 #include "setupapi_private.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
40 static FARPROC16 VCP_Proc = NULL;
41 static LPARAM VCP_MsgRef = 0;
43 static BOOL VCP_opened = FALSE;
45 static VCPSTATUS vcp_status;
47 static HINSTANCE SETUPAPI_hInstance;
49 static WORD VCP_Callback( LPVOID obj, UINT16 msg, WPARAM16 wParam, LPARAM lParam, LPARAM lParamRef )
55 args[7] = HIWORD(obj);
56 args[6] = LOWORD(obj);
59 args[3] = HIWORD(lParam);
60 args[2] = LOWORD(lParam);
61 args[1] = HIWORD(lParamRef);
62 args[0] = LOWORD(lParamRef);
63 WOWCallback16Ex( (DWORD)VCP_Proc, WCB16_PASCAL, sizeof(args), args, &ret );
68 /****************************** VHSTR management ******************************/
71 * This is a totally braindead implementation for now;
72 * I don't care about speed at all ! Size and implementation time
73 * is much more important IMHO. I could have created some sophisticated
74 * tree structure, but... what the hell ! :-)
81 static VHSTR_STRUCT **vhstrlist = NULL;
82 static VHSTR vhstr_alloc = 0;
84 #define VALID_VHSTR(x) ((x < vhstr_alloc) && (vhstrlist[x]) && (vhstrlist[x]->refcount))
86 /***********************************************************************
87 * vsmStringAdd (SETUPX.207)
89 VHSTR WINAPI vsmStringAdd16(LPCSTR lpszName)
95 TRACE("add string '%s'\n", lpszName);
96 /* search whether string already inserted */
97 TRACE("searching for existing string...\n");
98 for (n = 0; n < vhstr_alloc; n++)
100 if ((vhstrlist[n]) && (vhstrlist[n]->refcount))
102 TRACE("checking item: %d\n", n);
103 if (!strcmp(vhstrlist[n]->pStr, lpszName))
106 vhstrlist[n]->refcount++;
112 /* hmm, not found yet, let's insert it */
113 TRACE("inserting item\n");
114 for (n = 0; n < vhstr_alloc; n++)
116 if ((!(vhstrlist[n])) || (!(vhstrlist[n]->refcount)))
122 heap = GetProcessHeap();
123 if (n == vhstr_alloc) /* hmm, no free index found yet */
129 vhstrlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, vhstrlist,
130 sizeof(VHSTR_STRUCT *) * vhstr_alloc);
132 vhstrlist = HeapAlloc(heap, HEAP_ZERO_MEMORY,
133 sizeof(VHSTR_STRUCT *) * vhstr_alloc);
136 return 0xffff; /* failure */
137 if (!vhstrlist[index])
138 vhstrlist[index] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VHSTR_STRUCT));
139 vhstrlist[index]->refcount = 1;
140 vhstrlist[index]->pStr = HeapAlloc(heap, 0, strlen(lpszName)+1);
141 strcpy((LPSTR)vhstrlist[index]->pStr, lpszName);
145 /***********************************************************************
146 * vsmStringDelete (SETUPX.206)
148 INT16 WINAPI vsmStringDelete16(VHSTR vhstr)
150 if (VALID_VHSTR(vhstr))
152 vhstrlist[vhstr]->refcount--;
153 if (!vhstrlist[vhstr]->refcount)
155 HeapFree(GetProcessHeap(), 0, (LPSTR)vhstrlist[vhstr]->pStr);
156 vhstrlist[vhstr]->pStr = NULL;
161 /* string not found */
166 * vsmStringFind() - not exported from a standard SETUPX.DLL, it seems
168 VHSTR WINAPI vsmStringFind16(LPCSTR lpszName)
171 for (n = 0; n < vhstr_alloc; n++)
172 if ((vhstrlist[n]) && (vhstrlist[n]->refcount) && (!strcmp(vhstrlist[n]->pStr, lpszName)))
177 /***********************************************************************
178 * vsmGetStringName (SETUPX.205)
180 * Pretty correct, I guess
182 INT16 WINAPI vsmGetStringName16(VHSTR vhstr, LPSTR lpszBuffer, int cbBuffer)
184 if (VALID_VHSTR(vhstr))
186 int len = strlen(vhstrlist[vhstr]->pStr)+1;
190 strcpy(lpszBuffer, vhstrlist[vhstr]->pStr);
197 /***********************************************************************
198 * vsmStringCompare (not exported from a standard SETUPX.DLL, it seems)
200 INT16 WINAPI vsmStringCompare16(VHSTR vhstrA, VHSTR vhstrB)
202 if ((!VALID_VHSTR(vhstrA)) || (!VALID_VHSTR(vhstrB)))
203 return VCPN_FAIL; /* correct ? */
204 return strcmp(vhstrlist[vhstrA]->pStr, vhstrlist[vhstrB]->pStr);
207 /***********************************************************************
208 * vsmGetStringRawName (SETUPX.208)
210 LPCSTR WINAPI vsmGetStringRawName16(VHSTR vhstr)
212 return (VALID_VHSTR(vhstr)) ? vhstrlist[vhstr]->pStr : NULL;
216 /***************************** VIRTNODE management ****************************/
217 static LPVIRTNODE *pvnlist = NULL;
218 static DWORD vn_num = 0;
219 static DWORD vn_last = 0;
221 RETERR16 VCP_VirtnodeCreate(LPVCPFILESPEC vfsSrc, LPVCPFILESPEC vfsDst, WORD fl, LPARAM lParam, LPEXPANDVTBL lpExpandVtbl)
227 while (vn_last < vn_num)
229 if (pvnlist[vn_last] == NULL)
233 heap = GetProcessHeap();
234 if (vn_last == vn_num)
238 pvnlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, pvnlist,
239 sizeof(LPVIRTNODE *) * vn_num);
241 pvnlist = HeapAlloc(heap, HEAP_ZERO_MEMORY,
242 sizeof(LPVIRTNODE *) * vn_num);
244 pvnlist[vn_last] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VIRTNODE));
245 lpvn = pvnlist[vn_last];
248 lpvn->cbSize = sizeof(VIRTNODE);
251 memcpy(&lpvn->vfsSrc, vfsSrc, sizeof(VCPFILESPEC));
254 memcpy(&lpvn->vfsDst, vfsDst, sizeof(VCPFILESPEC));
257 lpvn->lParam = lParam;
258 lpvn->lpExpandVtbl = lpExpandVtbl;
260 lpvn->vhstrDstFinalName = 0xffff; /* FIXME: what is this ? */
262 cbres = VCP_Callback(lpvn, VCPM_NODECREATE, 0, 0, VCP_MsgRef);
263 lpvn->fl |= VFNL_CREATED;
264 cbres = VCP_Callback(lpvn, VCPM_NODEACCEPT, 0, 0, VCP_MsgRef);
269 BOOL VCP_VirtnodeDelete(LPVIRTNODE lpvnDel)
274 for (n = 0; n < vn_last; n++)
276 if (pvnlist[n] == lpvnDel)
278 cbres = VCP_Callback(lpvnDel, VCPM_NODEDESTROY, 0, 0, VCP_MsgRef);
279 HeapFree(GetProcessHeap(), 0, lpvnDel);
287 /***********************************************************************
288 * VcpOpen (SETUPX.200)
290 * Sets up a virtual copy operation.
291 * This means that functions such as GenInstall()
292 * create a VIRTNODE struct for every file to be touched in a .INF file
293 * instead of actually touching the file.
294 * The actual copy/move/rename gets started when VcpClose or
295 * VcpFlush is called; several different callbacks are made
296 * (copy, rename, open, close, version conflicts, ...) on every file copied.
298 RETERR16 WINAPI VcpOpen16(VIFPROC vifproc, LPARAM lparamMsgRef)
300 TRACE("(%p, %08lx)\n", vifproc, lparamMsgRef);
304 VCP_Proc = (FARPROC16)vifproc;
305 VCP_MsgRef = lparamMsgRef;
307 /* load SETUPAPI needed for dialog resources etc. */
308 SETUPAPI_hInstance = LoadLibraryA("setupapi.dll");
309 if (!SETUPAPI_hInstance)
311 ERR("Could not load sibling setupapi.dll\n");
312 return ERR_VCP_NOMEM;
318 /***********************************************************************
319 * VcpQueueCopy [SETUPX.13]
321 * lpExpandVtbl seems to be deprecated.
322 * fl are the CNFL_xxx and VNFL_xxx flags.
323 * lParam are the VNLP_xxx flags.
325 RETERR16 WINAPI VcpQueueCopy16(
326 LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
327 LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
328 LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
329 LPEXPANDVTBL lpExpandVtbl,
330 WORD fl, LPARAM lParam
333 VCPFILESPEC vfsSrc, vfsDst;
336 return ERR_VCP_NOTOPEN;
338 TRACE("srcdir: %s, srcfile: %s, dstdir: %s, dstfile: %s\n",
339 lpszSrcDir, lpszSrcFileName, lpszDstDir, lpszDstFileName);
341 TRACE("ldidSrc == %d, ldidDst == %d\n", ldidSrc, ldidDst);
343 vfsSrc.ldid = ldidSrc;
344 vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);
345 vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);
347 vfsDst.ldid = ldidDst;
348 vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
349 vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
351 return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, fl, lParam,
355 /***********************************************************************
356 * VcpQueueDelete [SETUPX.17]
358 * Is lParamRef the same as lParam in VcpQueueCopy ?
359 * Damn docu !! Err... which docu ?
361 RETERR16 WINAPI VcpQueueDelete16(
362 LPCSTR lpszDstFileName,
371 return ERR_VCP_NOTOPEN;
373 vfsDst.ldid = ldidDst;
374 vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
375 vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
377 return VCP_VirtnodeCreate(NULL, &vfsDst, VNFL_DELETE, lParamRef, 0);
380 /***********************************************************************
381 * VcpQueueRename [SETUPX.204]
384 RETERR16 WINAPI VcpQueueRename16(
385 LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
386 LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
387 LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
391 VCPFILESPEC vfsSrc, vfsDst;
394 return ERR_VCP_NOTOPEN;
396 vfsSrc.ldid = ldidSrc;
397 vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);
398 vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);
400 vfsDst.ldid = ldidDst;
401 vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
402 vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
404 return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, VNFL_RENAME, lParam,
408 /***********************************************************************
409 * VcpEnumFiles (SETUPX.@)
411 INT16 WINAPI VcpEnumFiles(VCPENUMPROC vep, LPARAM lParamRef)
415 for (n = 0; n < vn_last; n++)
416 vep(pvnlist[n], lParamRef);
418 return 0; /* FIXME: return value ? */
421 /***********************************************************************
422 * VcpExplain (SETUPX.411)
424 LPCSTR WINAPI VcpExplain16(LPVIRTNODE lpVn, DWORD dwWhat)
426 static char buffer[MAX_PATH]; /* FIXME: is this how it's done ? */
433 LPVCPFILESPEC lpvfs =
434 (dwWhat == VCPEX_SRC_FULL) ? &lpVn->vfsSrc : &lpVn->vfsDst;
436 /* if we have an ldid, use it, otherwise use the string */
437 /* from the vhstrlist array */
438 if (lpvfs->ldid != 0xffff)
439 CtlGetLddPath16(lpvfs->ldid, buffer);
441 strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrDir));
443 strcat(buffer, "\\");
444 strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrFileName));
448 FIXME("%ld unimplemented !\n", dwWhat);
449 strcpy(buffer, "Unknown error");
455 RETERR16 VCP_CheckPaths(void)
461 cbres = VCP_Callback(&vcp_status, VCPM_VSTATPATHCHECKSTART, 0, 0, VCP_MsgRef);
462 for (n = 0; n < vn_num; n++)
466 /* FIXME: check paths of all VIRTNODEs here ! */
467 cbres = VCP_Callback(&lpvn->vfsDst, VCPM_CHECKPATH, 0, (DWORD)lpvn, VCP_MsgRef);
469 cbres = VCP_Callback(&vcp_status, VCPM_VSTATPATHCHECKEND, 0, 0, VCP_MsgRef);
473 RETERR16 VCP_CopyFiles(void)
475 char fn_src[MAX_PATH], fn_dst[MAX_PATH];
476 RETERR16 res = OK, cbres;
480 cbres = VCP_Callback(&vcp_status, VCPM_VSTATCOPYSTART, 0, 0, VCP_MsgRef);
481 for (n = 0; n < vn_num; n++)
484 if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_COPY)) continue;
485 /* FIXME: need to send VCPM_VSTATNEWDISK notification sometimes */
486 strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));
487 strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));
488 /* FIXME: what is this VCPM_VSTATWRITE here for ?
489 * I guess it's to signal successful destination file creation */
490 cbres = VCP_Callback(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);
492 /* FIXME: need to do the file copy in small chunks for notifications */
493 TRACE("copying '%s' to '%s'\n", fn_src, fn_dst);
494 /* perform the file copy */
495 if (!(CopyFileA(fn_src, fn_dst,
496 (lpvn->fl & VNLP_COPYIFEXISTS) ? FALSE : TRUE )))
498 ERR("error copying, src: %s -> dst: %s\n", fn_src, fn_dst);
499 res = ERR_VCP_IOFAIL;
502 vcp_status.prgFileRead.dwSoFar++;
503 cbres = VCP_Callback(&vcp_status, VCPM_VSTATREAD, 0, 0, VCP_MsgRef);
504 vcp_status.prgFileWrite.dwSoFar++;
505 cbres = VCP_Callback(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);
508 cbres = VCP_Callback(&vcp_status, VCPM_VSTATCOPYEND, 0, 0, VCP_MsgRef);
512 /***********************************************************************
513 * VcpFlush - internal (not exported), but documented
515 * VNFL_NOW is used for VcpFlush.
517 RETERR16 VcpFlush16(WORD fl, LPCSTR lpszBackupDest)
522 /***********************************************************************
523 * VcpClose (SETUPX.201)
525 * Does callbacks (-> vifproc) with VCPM_VSTATCLOSESTART,
526 * VCPM_VSTATCLOSEEND.
528 * fl gets VCPFL_xxx flags to indicate what to do with the
529 * VIRTNODEs (files to mess with) created by e.g. GenInstall()
531 RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest)
534 WORD cbres = VCPN_PROCEED;
536 TRACE("(%04x, '%s')\n", fl, lpszBackupDest);
538 /* FIXME: needs to sort virtnodes in case VCPFL_INSPECIFIEDORDER
539 * is not set. This is done by VCP_Callback(VCPM_NODECOMPARE) */
542 memset(&vcp_status, 0, sizeof(VCPSTATUS));
543 /* yes, vcp_status.cbSize is 0 ! */
545 cbres = VCP_Callback(&vcp_status, VCPM_VSTATCLOSESTART, 0, 0, VCP_MsgRef);
548 res = VCP_CheckPaths();
551 return res; /* is this ok ? */
555 cbres = VCP_Callback(&vcp_status, VCPM_VSTATCLOSEEND, 0, 0, VCP_MsgRef);
558 FreeLibrary(SETUPAPI_hInstance);
563 RETERR16 VCP_RenameFiles(void)
565 char fn_src[MAX_PATH], fn_dst[MAX_PATH];
566 RETERR16 res = OK, cbres;
570 cbres = VCP_Callback(&vcp_status, VCPM_VSTATRENAMESTART, 0, 0, VCP_MsgRef);
571 for (n = 0; n < vn_num; n++)
574 if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_RENAME)) continue;
575 strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));
576 strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));
577 cbres = VCP_Callback(&lpvn->vfsDst, VCPM_FILEOPENOUT, 0, (LPARAM)lpvn, VCP_MsgRef);
578 if (!(MoveFileExA(fn_src, fn_dst, MOVEFILE_REPLACE_EXISTING)))
579 res = ERR_VCP_IOFAIL;
581 VCP_VirtnodeDelete(lpvn);
583 cbres = VCP_Callback(&vcp_status, VCPM_VSTATRENAMEEND, 0, 0, VCP_MsgRef);
587 /***********************************************************************
588 * vcpDefCallbackProc (SETUPX.202)
590 RETERR16 WINAPI vcpDefCallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
591 LPARAM lParam, LPARAM lParamRef)
593 static int count = 0;
595 FIXME("(%p, %04x, %04x, %08lx, %08lx) - what to do here ?\n",
596 lpvObj, uMsg, wParam, lParam, lParamRef);
601 /********************* point-and-click stuff from here ***********************/
603 static HWND hDlgCopy = 0;
604 static HKEY hKeyFiles = 0, hKeyRename = 0, hKeyConflict = 0;
605 static char BackupDir[12];
607 static INT_PTR CALLBACK VCP_UI_FileCopyDlgProc(HWND hWndDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
609 INT_PTR retval = FALSE;
611 if (iMsg == WM_INITDIALOG)
613 ShowWindow(hWndDlg, SW_SHOWNORMAL);
614 UpdateWindow(hWndDlg);
620 BOOL VCP_UI_GetDialogTemplate(LPCVOID *template32)
625 if (!(hResInfo = FindResourceA(SETUPAPI_hInstance, MAKEINTRESOURCEA(COPYFILEDLGORD), (LPSTR)RT_DIALOG)))
627 if (!(hDlgTmpl32 = LoadResource(SETUPAPI_hInstance, hResInfo )) ||
628 !(*template32 = LockResource( hDlgTmpl32 )))
633 static LRESULT WINAPI
634 VCP_UI_FileCopyWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
636 if (uMsg != WM_CREATE)
637 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
644 FIXME("%04x: unhandled.\n", uMsg);
650 void VCP_UI_RegisterProgressClass(void)
652 static BOOL registered = FALSE;
659 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
660 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
661 wndClass.lpfnWndProc = VCP_UI_FileCopyWndProc;
662 wndClass.cbClsExtra = 0;
663 wndClass.cbWndExtra = 0;
664 wndClass.hCursor = LoadCursorA (0, (LPSTR)IDC_ARROW);
665 wndClass.hbrBackground = NULL;
666 wndClass.lpszClassName = "setupx_progress";
668 RegisterClassA (&wndClass);
671 RETERR16 VCP_UI_NodeCompare(LPVIRTNODE vn1, LPVIRTNODE vn2)
674 file1 = vsmGetStringRawName16(vn1->vfsSrc.vhstrFileName);
675 file2 = vsmGetStringRawName16(vn2->vfsSrc.vhstrFileName);
676 return (RETERR16)strcmp(file1, file2);
679 RETERR16 VCP_UI_CopyStart(void)
682 char buf[256]; /* plenty */
686 /* FIXME: should be registered at DLL startup instead */
687 VCP_UI_RegisterProgressClass();
688 if (!(VCP_UI_GetDialogTemplate(&template32)))
691 if (vn_num > 10) /* hack */
693 hDlgCopy = CreateDialogIndirectParamA(SETUPAPI_hInstance, template32, 0,
694 VCP_UI_FileCopyDlgProc, 0);
697 SetDlgItemTextA(hDlgCopy, SOURCESTRORD, "Scanning ...");
698 SetDlgItemTextA(hDlgCopy, DESTSTRORD, "NOT_IMPLEMENTED_YET");
700 strcpy(buf, REG_INSTALLEDFILES);
701 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyFiles))
703 strcat(buf, REGPART_RENAME);
704 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyRename))
706 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT, &hKeyConflict))
709 if (!(RegQueryValueExA(hKeyConflict, "Dirty", NULL, 0, (LPBYTE)&dirty, &len)))
711 /* FIXME: what does SETUPX.DLL do in this case ? */
712 MESSAGE("Warning: another program using SETUPX is already running ! Failed.\n");
716 if (RegSetValueExA(hKeyConflict, "Dirty", 0, REG_BINARY, (LPBYTE)&dirty, 1))
719 if (!(RegQueryValueExA(hKeyConflict, "BackupDirectory", NULL, 0, BackupDir, &len)))
720 strcpy(BackupDir, "VCM");
722 /* create C:\WINDOWS\[BackupDir] and set registry key to it */
723 GetWindowsDirectoryA(buf, 256);
725 strcat(buf, BackupDir);
726 if (!(CreateDirectoryA(buf, NULL)))
728 if (RegSetValueExA(hKeyConflict, "BackupDirectory", 0, REG_SZ, (LPBYTE)buf, strlen(buf)+1))
730 RegCloseKey(hKeyConflict);
735 /***********************************************************************
736 * vcpUICallbackProc (SETUPX.213)
738 RETERR16 WINAPI vcpUICallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
739 LPARAM lParam, LPARAM lParamRef)
741 static int count = 0;
742 RETERR16 res = VCPN_OK, cbres;
745 FIXME("(%p, %04x, %04x, %08lx, %08lx) - semi-stub\n",
746 lpvObj, uMsg, wParam, lParam, lParamRef);
750 /* unused messages, it seems */
751 case VCPM_DISKPREPINFO:
753 case VCPM_FILENEEDED:
755 case VCPM_NODECREATE:
756 case VCPM_NODEACCEPT:
758 case VCPM_VSTATCLOSESTART:
759 case VCPM_VSTATPATHCHECKSTART:
760 case VCPM_VSTATPATHCHECKEND:
766 case VCPM_NODECOMPARE:
767 res = VCP_UI_NodeCompare((LPVIRTNODE)lpvObj, (LPVIRTNODE)lParam);
771 case VCPM_VSTATWRITE:
772 cbres = VCP_Callback(&vcp_status, VCPM_DISKPREPINFO, 0, 0, VCP_MsgRef);
774 case VCPM_VSTATCLOSEEND:
775 RegCloseKey(hKeyFiles);
776 RegCloseKey(hKeyRename);
777 RegDeleteKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT);
779 case VCPM_VSTATCOPYSTART:
780 res = VCP_UI_CopyStart();
782 case VCPM_VSTATCOPYEND:
783 if (hDlgCopy) DestroyWindow(hDlgCopy);
786 FIXME("unhandled msg 0x%04x\n", uMsg);