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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 static 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);
270 static BOOL VCP_VirtnodeDelete(LPVIRTNODE lpvnDel)
275 for (n = 0; n < vn_last; n++)
277 if (pvnlist[n] == lpvnDel)
279 cbres = VCP_Callback(lpvnDel, VCPM_NODEDESTROY, 0, 0, VCP_MsgRef);
280 HeapFree(GetProcessHeap(), 0, lpvnDel);
289 /***********************************************************************
290 * VcpOpen (SETUPX.200)
292 * Sets up a virtual copy operation.
293 * This means that functions such as GenInstall()
294 * create a VIRTNODE struct for every file to be touched in a .INF file
295 * instead of actually touching the file.
296 * The actual copy/move/rename gets started when VcpClose or
297 * VcpFlush is called; several different callbacks are made
298 * (copy, rename, open, close, version conflicts, ...) on every file copied.
300 RETERR16 WINAPI VcpOpen16(VIFPROC vifproc, LPARAM lparamMsgRef)
302 TRACE("(%p, %08lx)\n", vifproc, lparamMsgRef);
306 VCP_Proc = (FARPROC16)vifproc;
307 VCP_MsgRef = lparamMsgRef;
309 /* load SETUPAPI needed for dialog resources etc. */
310 SETUPAPI_hInstance = GetModuleHandleA("setupapi.dll");
311 if (!SETUPAPI_hInstance)
313 ERR("Could not load sibling setupapi.dll\n");
314 return ERR_VCP_NOMEM;
320 /***********************************************************************
321 * VcpQueueCopy [SETUPX.13]
323 * lpExpandVtbl seems to be deprecated.
324 * fl are the CNFL_xxx and VNFL_xxx flags.
325 * lParam are the VNLP_xxx flags.
327 RETERR16 WINAPI VcpQueueCopy16(
328 LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
329 LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
330 LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
331 LPEXPANDVTBL lpExpandVtbl,
332 WORD fl, LPARAM lParam
335 VCPFILESPEC vfsSrc, vfsDst;
338 return ERR_VCP_NOTOPEN;
340 TRACE("srcdir: %s, srcfile: %s, dstdir: %s, dstfile: %s\n",
341 lpszSrcDir, lpszSrcFileName, lpszDstDir, lpszDstFileName);
343 TRACE("ldidSrc == %d, ldidDst == %d\n", ldidSrc, ldidDst);
345 vfsSrc.ldid = ldidSrc;
346 vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);
347 vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);
349 vfsDst.ldid = ldidDst;
350 vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
351 vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
353 return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, fl, lParam,
357 /***********************************************************************
358 * VcpQueueDelete [SETUPX.17]
360 * Is lParamRef the same as lParam in VcpQueueCopy ?
361 * Damn docu !! Err... which docu ?
363 RETERR16 WINAPI VcpQueueDelete16(
364 LPCSTR lpszDstFileName,
373 return ERR_VCP_NOTOPEN;
375 vfsDst.ldid = ldidDst;
376 vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
377 vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
379 return VCP_VirtnodeCreate(NULL, &vfsDst, VNFL_DELETE, lParamRef, 0);
382 /***********************************************************************
383 * VcpQueueRename [SETUPX.204]
386 RETERR16 WINAPI VcpQueueRename16(
387 LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
388 LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
389 LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
393 VCPFILESPEC vfsSrc, vfsDst;
396 return ERR_VCP_NOTOPEN;
398 vfsSrc.ldid = ldidSrc;
399 vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);
400 vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);
402 vfsDst.ldid = ldidDst;
403 vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
404 vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
406 return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, VNFL_RENAME, lParam,
410 /***********************************************************************
411 * VcpEnumFiles (SETUPX.@)
413 INT16 WINAPI VcpEnumFiles(VCPENUMPROC vep, LPARAM lParamRef)
417 for (n = 0; n < vn_last; n++)
418 vep(pvnlist[n], lParamRef);
420 return 0; /* FIXME: return value ? */
423 /***********************************************************************
424 * VcpExplain (SETUPX.411)
426 LPCSTR WINAPI VcpExplain16(LPVIRTNODE lpVn, DWORD dwWhat)
428 static char buffer[MAX_PATH]; /* FIXME: is this how it's done ? */
435 LPVCPFILESPEC lpvfs =
436 (dwWhat == VCPEX_SRC_FULL) ? &lpVn->vfsSrc : &lpVn->vfsDst;
438 /* if we have an ldid, use it, otherwise use the string */
439 /* from the vhstrlist array */
440 if (lpvfs->ldid != 0xffff)
441 CtlGetLddPath16(lpvfs->ldid, buffer);
443 strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrDir));
445 strcat(buffer, "\\");
446 strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrFileName));
450 FIXME("%ld unimplemented !\n", dwWhat);
451 strcpy(buffer, "Unknown error");
457 static RETERR16 VCP_CheckPaths(void)
463 cbres = VCP_Callback(&vcp_status, VCPM_VSTATPATHCHECKSTART, 0, 0, VCP_MsgRef);
464 for (n = 0; n < vn_num; n++)
468 /* FIXME: check paths of all VIRTNODEs here ! */
469 cbres = VCP_Callback(&lpvn->vfsDst, VCPM_CHECKPATH, 0, (DWORD)lpvn, VCP_MsgRef);
471 cbres = VCP_Callback(&vcp_status, VCPM_VSTATPATHCHECKEND, 0, 0, VCP_MsgRef);
475 static RETERR16 VCP_CopyFiles(void)
477 char fn_src[MAX_PATH], fn_dst[MAX_PATH];
478 RETERR16 res = OK, cbres;
482 cbres = VCP_Callback(&vcp_status, VCPM_VSTATCOPYSTART, 0, 0, VCP_MsgRef);
483 for (n = 0; n < vn_num; n++)
486 if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_COPY)) continue;
487 /* FIXME: need to send VCPM_VSTATNEWDISK notification sometimes */
488 strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));
489 strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));
490 /* FIXME: what is this VCPM_VSTATWRITE here for ?
491 * I guess it's to signal successful destination file creation */
492 cbres = VCP_Callback(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);
494 /* FIXME: need to do the file copy in small chunks for notifications */
495 TRACE("copying '%s' to '%s'\n", fn_src, fn_dst);
496 /* perform the file copy */
497 if (!(CopyFileA(fn_src, fn_dst,
498 (lpvn->fl & VNLP_COPYIFEXISTS) ? FALSE : TRUE )))
500 ERR("error copying, src: %s -> dst: %s\n", fn_src, fn_dst);
501 res = ERR_VCP_IOFAIL;
504 vcp_status.prgFileRead.dwSoFar++;
505 cbres = VCP_Callback(&vcp_status, VCPM_VSTATREAD, 0, 0, VCP_MsgRef);
506 vcp_status.prgFileWrite.dwSoFar++;
507 cbres = VCP_Callback(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);
510 cbres = VCP_Callback(&vcp_status, VCPM_VSTATCOPYEND, 0, 0, VCP_MsgRef);
514 /***********************************************************************
515 * VcpFlush - internal (not exported), but documented
517 * VNFL_NOW is used for VcpFlush.
519 RETERR16 VcpFlush16(WORD fl, LPCSTR lpszBackupDest)
524 /***********************************************************************
525 * VcpClose (SETUPX.201)
527 * Does callbacks (-> vifproc) with VCPM_VSTATCLOSESTART,
528 * VCPM_VSTATCLOSEEND.
530 * fl gets VCPFL_xxx flags to indicate what to do with the
531 * VIRTNODEs (files to mess with) created by e.g. GenInstall()
533 RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest)
536 WORD cbres = VCPN_PROCEED;
538 TRACE("(%04x, '%s')\n", fl, lpszBackupDest);
540 /* FIXME: needs to sort virtnodes in case VCPFL_INSPECIFIEDORDER
541 * is not set. This is done by VCP_Callback(VCPM_NODECOMPARE) */
544 memset(&vcp_status, 0, sizeof(VCPSTATUS));
545 /* yes, vcp_status.cbSize is 0 ! */
547 cbres = VCP_Callback(&vcp_status, VCPM_VSTATCLOSESTART, 0, 0, VCP_MsgRef);
550 res = VCP_CheckPaths();
553 return res; /* is this ok ? */
557 cbres = VCP_Callback(&vcp_status, VCPM_VSTATCLOSEEND, 0, 0, VCP_MsgRef);
565 static RETERR16 VCP_RenameFiles(void)
567 char fn_src[MAX_PATH], fn_dst[MAX_PATH];
568 RETERR16 res = OK, cbres;
572 cbres = VCP_Callback(&vcp_status, VCPM_VSTATRENAMESTART, 0, 0, VCP_MsgRef);
573 for (n = 0; n < vn_num; n++)
576 if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_RENAME)) continue;
577 strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));
578 strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));
579 cbres = VCP_Callback(&lpvn->vfsDst, VCPM_FILEOPENOUT, 0, (LPARAM)lpvn, VCP_MsgRef);
580 if (!(MoveFileExA(fn_src, fn_dst, MOVEFILE_REPLACE_EXISTING)))
581 res = ERR_VCP_IOFAIL;
583 VCP_VirtnodeDelete(lpvn);
585 cbres = VCP_Callback(&vcp_status, VCPM_VSTATRENAMEEND, 0, 0, VCP_MsgRef);
590 /***********************************************************************
591 * vcpDefCallbackProc (SETUPX.202)
593 RETERR16 WINAPI vcpDefCallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
594 LPARAM lParam, LPARAM lParamRef)
596 static int count = 0;
598 FIXME("(%p, %04x, %04x, %08lx, %08lx) - what to do here ?\n",
599 lpvObj, uMsg, wParam, lParam, lParamRef);
604 /********************* point-and-click stuff from here ***********************/
606 static HWND hDlgCopy = 0;
607 static HKEY hKeyFiles = 0, hKeyRename = 0, hKeyConflict = 0;
608 static char BackupDir[12];
610 static INT_PTR CALLBACK VCP_UI_FileCopyDlgProc(HWND hWndDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
612 INT_PTR retval = FALSE;
614 if (iMsg == WM_INITDIALOG)
616 ShowWindow(hWndDlg, SW_SHOWNORMAL);
617 UpdateWindow(hWndDlg);
623 static BOOL VCP_UI_GetDialogTemplate(LPCVOID *template32)
628 if (!(hResInfo = FindResourceA(SETUPAPI_hInstance, MAKEINTRESOURCEA(COPYFILEDLGORD), (LPSTR)RT_DIALOG)))
630 if (!(hDlgTmpl32 = LoadResource(SETUPAPI_hInstance, hResInfo )) ||
631 !(*template32 = LockResource( hDlgTmpl32 )))
636 static LRESULT WINAPI
637 VCP_UI_FileCopyWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
639 if (uMsg != WM_CREATE)
640 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
647 FIXME("%04x: unhandled.\n", uMsg);
653 static void VCP_UI_RegisterProgressClass(void)
655 static BOOL registered = FALSE;
662 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
663 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
664 wndClass.lpfnWndProc = VCP_UI_FileCopyWndProc;
665 wndClass.cbClsExtra = 0;
666 wndClass.cbWndExtra = 0;
667 wndClass.hCursor = LoadCursorA (0, (LPSTR)IDC_ARROW);
668 wndClass.hbrBackground = NULL;
669 wndClass.lpszClassName = "setupx_progress";
671 RegisterClassA (&wndClass);
674 static RETERR16 VCP_UI_NodeCompare(LPVIRTNODE vn1, LPVIRTNODE vn2)
677 file1 = vsmGetStringRawName16(vn1->vfsSrc.vhstrFileName);
678 file2 = vsmGetStringRawName16(vn2->vfsSrc.vhstrFileName);
679 return (RETERR16)strcmp(file1, file2);
682 static RETERR16 VCP_UI_CopyStart(void)
685 char buf[256]; /* plenty */
689 /* FIXME: should be registered at DLL startup instead */
690 VCP_UI_RegisterProgressClass();
691 if (!(VCP_UI_GetDialogTemplate(&template32)))
694 if (vn_num > 10) /* hack */
696 hDlgCopy = CreateDialogIndirectParamA(SETUPAPI_hInstance, template32, 0,
697 VCP_UI_FileCopyDlgProc, 0);
700 SetDlgItemTextA(hDlgCopy, SOURCESTRORD, "Scanning ...");
701 SetDlgItemTextA(hDlgCopy, DESTSTRORD, "NOT_IMPLEMENTED_YET");
703 strcpy(buf, REG_INSTALLEDFILES);
704 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyFiles))
706 strcat(buf, REGPART_RENAME);
707 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyRename))
709 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT, &hKeyConflict))
712 if (!(RegQueryValueExA(hKeyConflict, "Dirty", NULL, 0, (LPBYTE)&dirty, &len)))
714 /* FIXME: what does SETUPX.DLL do in this case ? */
715 MESSAGE("Warning: another program using SETUPX is already running ! Failed.\n");
719 if (RegSetValueExA(hKeyConflict, "Dirty", 0, REG_BINARY, (LPBYTE)&dirty, 1))
722 if (!(RegQueryValueExA(hKeyConflict, "BackupDirectory", NULL, 0, (LPBYTE)BackupDir, &len)))
723 strcpy(BackupDir, "VCM");
725 /* create C:\WINDOWS\[BackupDir] and set registry key to it */
726 GetWindowsDirectoryA(buf, 256);
728 strcat(buf, BackupDir);
729 if (!(CreateDirectoryA(buf, NULL)))
731 if (RegSetValueExA(hKeyConflict, "BackupDirectory", 0, REG_SZ, (LPBYTE)buf, strlen(buf)+1))
733 RegCloseKey(hKeyConflict);
738 /***********************************************************************
739 * vcpUICallbackProc (SETUPX.213)
741 RETERR16 WINAPI vcpUICallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
742 LPARAM lParam, LPARAM lParamRef)
744 static int count = 0;
745 RETERR16 res = VCPN_OK, cbres;
748 FIXME("(%p, %04x, %04x, %08lx, %08lx) - semi-stub\n",
749 lpvObj, uMsg, wParam, lParam, lParamRef);
753 /* unused messages, it seems */
754 case VCPM_DISKPREPINFO:
756 case VCPM_FILENEEDED:
758 case VCPM_NODECREATE:
759 case VCPM_NODEACCEPT:
761 case VCPM_VSTATCLOSESTART:
762 case VCPM_VSTATPATHCHECKSTART:
763 case VCPM_VSTATPATHCHECKEND:
769 case VCPM_NODECOMPARE:
770 res = VCP_UI_NodeCompare((LPVIRTNODE)lpvObj, (LPVIRTNODE)lParam);
774 case VCPM_VSTATWRITE:
775 cbres = VCP_Callback(&vcp_status, VCPM_DISKPREPINFO, 0, 0, VCP_MsgRef);
777 case VCPM_VSTATCLOSEEND:
778 RegCloseKey(hKeyFiles);
779 RegCloseKey(hKeyRename);
780 RegDeleteKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT);
782 case VCPM_VSTATCOPYSTART:
783 res = VCP_UI_CopyStart();
785 case VCPM_VSTATCOPYEND:
786 if (hDlgCopy) DestroyWindow(hDlgCopy);
789 FIXME("unhandled msg 0x%04x\n", uMsg);