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.
30 #include "setupapi_private.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
35 /* ### start build ### */
36 extern WORD CALLBACK VCP_CallTo16_word_lwwll(FARPROC16,LPVOID,UINT16,WPARAM,LPARAM,LPARAM);
37 /* ### stop build ### */
39 static FARPROC16 VCP_Proc = NULL;
40 static LPARAM VCP_MsgRef = 0;
42 #define VCP_CALLBACK(obj,msg,wParam,lParam,lParamRef) \
44 VCP_CallTo16_word_lwwll(VCP_Proc, obj,msg,wParam,lParam,lParamRef) : OK;
46 static BOOL VCP_opened = FALSE;
48 static VCPSTATUS vcp_status;
50 static HINSTANCE SETUPAPI_hInstance;
52 /****************************** VHSTR management ******************************/
55 * This is a totally braindead implementation for now;
56 * I don't care about speed at all ! Size and implementation time
57 * is much more important IMHO. I could have created some sophisticated
58 * tree structure, but... what the hell ! :-)
65 static VHSTR_STRUCT **vhstrlist = NULL;
66 static VHSTR vhstr_alloc = 0;
68 #define VALID_VHSTR(x) ((x < vhstr_alloc) && (vhstrlist[x]) && (vhstrlist[x]->refcount))
70 /***********************************************************************
71 * vsmStringAdd (SETUPX.207)
73 VHSTR WINAPI vsmStringAdd16(LPCSTR lpszName)
79 TRACE("add string '%s'\n", lpszName);
80 /* search whether string already inserted */
81 TRACE("searching for existing string...\n");
82 for (n = 0; n < vhstr_alloc; n++)
84 if ((vhstrlist[n]) && (vhstrlist[n]->refcount))
86 TRACE("checking item: %d\n", n);
87 if (!strcmp(vhstrlist[n]->pStr, lpszName))
90 vhstrlist[n]->refcount++;
96 /* hmm, not found yet, let's insert it */
97 TRACE("inserting item\n");
98 for (n = 0; n < vhstr_alloc; n++)
100 if ((!(vhstrlist[n])) || (!(vhstrlist[n]->refcount)))
106 heap = GetProcessHeap();
107 if (n == vhstr_alloc) /* hmm, no free index found yet */
111 vhstrlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, vhstrlist,
112 sizeof(VHSTR_STRUCT *) * vhstr_alloc);
115 return 0xffff; /* failure */
116 if (!vhstrlist[index])
117 vhstrlist[index] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VHSTR_STRUCT));
118 vhstrlist[index]->refcount = 1;
119 vhstrlist[index]->pStr = HeapAlloc(heap, 0, strlen(lpszName)+1);
120 strcpy((LPSTR)vhstrlist[index]->pStr, lpszName);
124 /***********************************************************************
125 * vsmStringDelete (SETUPX.206)
127 INT16 WINAPI vsmStringDelete16(VHSTR vhstr)
129 if (VALID_VHSTR(vhstr))
131 vhstrlist[vhstr]->refcount--;
132 if (!vhstrlist[vhstr]->refcount)
134 HeapFree(GetProcessHeap(), 0, (LPSTR)vhstrlist[vhstr]->pStr);
135 vhstrlist[vhstr]->pStr = NULL;
140 /* string not found */
145 * vsmStringFind() - not exported from a standard SETUPX.DLL, it seems
147 VHSTR WINAPI vsmStringFind16(LPCSTR lpszName)
150 for (n = 0; n < vhstr_alloc; n++)
151 if ((vhstrlist[n]) && (vhstrlist[n]->refcount) && (!strcmp(vhstrlist[n]->pStr, lpszName)))
156 /***********************************************************************
157 * vsmGetStringName (SETUPX.205)
159 * Pretty correct, I guess
161 INT16 WINAPI vsmGetStringName16(VHSTR vhstr, LPSTR lpszBuffer, int cbBuffer)
163 if (VALID_VHSTR(vhstr))
165 int len = strlen(vhstrlist[vhstr]->pStr)+1;
169 strcpy(lpszBuffer, vhstrlist[vhstr]->pStr);
176 /***********************************************************************
177 * vsmStringCompare (not exported from a standard SETUPX.DLL, it seems)
179 INT16 WINAPI vsmStringCompare16(VHSTR vhstrA, VHSTR vhstrB)
181 if ((!VALID_VHSTR(vhstrA)) || (!VALID_VHSTR(vhstrB)))
182 return VCPN_FAIL; /* correct ? */
183 return strcmp(vhstrlist[vhstrA]->pStr, vhstrlist[vhstrB]->pStr);
186 /***********************************************************************
187 * vsmGetStringRawName (SETUPX.208)
189 LPCSTR WINAPI vsmGetStringRawName16(VHSTR vhstr)
191 return (VALID_VHSTR(vhstr)) ? vhstrlist[vhstr]->pStr : NULL;
195 /***************************** VIRTNODE management ****************************/
196 static LPVIRTNODE *pvnlist = NULL;
197 static DWORD vn_num = 0;
198 static DWORD vn_last = 0;
200 RETERR16 VCP_VirtnodeCreate(LPVCPFILESPEC vfsSrc, LPVCPFILESPEC vfsDst, WORD fl, LPARAM lParam, LPEXPANDVTBL lpExpandVtbl)
206 while (vn_last < vn_num)
208 if (pvnlist[vn_last] == NULL)
212 heap = GetProcessHeap();
213 if (vn_last == vn_num)
216 pvnlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, pvnlist,
217 sizeof(LPVIRTNODE *) * vn_num);
219 pvnlist[vn_last] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VIRTNODE));
220 lpvn = pvnlist[vn_last];
223 lpvn->cbSize = sizeof(VIRTNODE);
226 memcpy(&lpvn->vfsSrc, vfsSrc, sizeof(VCPFILESPEC));
229 memcpy(&lpvn->vfsDst, vfsDst, sizeof(VCPFILESPEC));
232 lpvn->lParam = lParam;
233 lpvn->lpExpandVtbl = lpExpandVtbl;
235 lpvn->vhstrDstFinalName = 0xffff; /* FIXME: what is this ? */
237 cbres = VCP_CALLBACK(lpvn, VCPM_NODECREATE, 0, 0, VCP_MsgRef);
238 lpvn->fl |= VFNL_CREATED;
239 cbres = VCP_CALLBACK(lpvn, VCPM_NODEACCEPT, 0, 0, VCP_MsgRef);
244 BOOL VCP_VirtnodeDelete(LPVIRTNODE lpvnDel)
249 for (n = 0; n < vn_last; n++)
251 if (pvnlist[n] == lpvnDel)
253 cbres = VCP_CALLBACK(lpvnDel, VCPM_NODEDESTROY, 0, 0, VCP_MsgRef);
254 HeapFree(GetProcessHeap(), 0, lpvnDel);
262 /***********************************************************************
263 * VcpOpen (SETUPX.200)
265 * Sets up a virtual copy operation.
266 * This means that functions such as GenInstall()
267 * create a VIRTNODE struct for every file to be touched in a .INF file
268 * instead of actually touching the file.
269 * The actual copy/move/rename gets started when VcpClose or
270 * VcpFlush is called; several different callbacks are made
271 * (copy, rename, open, close, version conflicts, ...) on every file copied.
273 RETERR16 WINAPI VcpOpen16(VIFPROC vifproc, LPARAM lparamMsgRef)
275 TRACE("(%p, %08lx)\n", vifproc, lparamMsgRef);
279 VCP_Proc = (FARPROC16)vifproc;
280 VCP_MsgRef = lparamMsgRef;
282 /* load SETUPAPI needed for dialog resources etc. */
283 SETUPAPI_hInstance = LoadLibraryA("setupapi.dll");
284 if (!SETUPAPI_hInstance)
286 ERR("Could not load sibling setupapi.dll\n");
287 return ERR_VCP_NOMEM;
293 /***********************************************************************
294 * VcpQueueCopy [SETUPX.13]
296 * lpExpandVtbl seems to be deprecated.
297 * fl are the CNFL_xxx and VNFL_xxx flags.
298 * lParam are the VNLP_xxx flags.
300 RETERR16 WINAPI VcpQueueCopy16(
301 LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
302 LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
303 LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
304 LPEXPANDVTBL lpExpandVtbl,
305 WORD fl, LPARAM lParam
308 VCPFILESPEC vfsSrc, vfsDst;
311 return ERR_VCP_NOTOPEN;
313 TRACE("srcdir: %s, srcfile: %s, dstdir: %s, dstfile: %s\n",
314 lpszSrcDir, lpszSrcFileName, lpszDstDir, lpszDstFileName);
316 TRACE("ldidSrc == %d, ldidDst == %d\n", ldidSrc, ldidDst);
318 vfsSrc.ldid = ldidSrc;
319 vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);
320 vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);
322 vfsDst.ldid = ldidDst;
323 vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
324 vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
326 return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, fl, lParam,
330 /***********************************************************************
331 * VcpQueueDelete [SETUPX.17]
333 * Is lParamRef the same as lParam in VcpQueueCopy ?
334 * Damn docu !! Err... which docu ?
336 RETERR16 WINAPI VcpQueueDelete16(
337 LPCSTR lpszDstFileName,
346 return ERR_VCP_NOTOPEN;
348 vfsDst.ldid = ldidDst;
349 vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
350 vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
352 return VCP_VirtnodeCreate(NULL, &vfsDst, VNFL_DELETE, lParamRef, 0);
355 /***********************************************************************
356 * VcpQueueRename [SETUPX.204]
359 RETERR16 WINAPI VcpQueueRename16(
360 LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
361 LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
362 LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
366 VCPFILESPEC vfsSrc, vfsDst;
369 return ERR_VCP_NOTOPEN;
371 vfsSrc.ldid = ldidSrc;
372 vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);
373 vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);
375 vfsDst.ldid = ldidDst;
376 vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
377 vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
379 return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, VNFL_RENAME, lParam,
383 /***********************************************************************
384 * VcpEnumFiles (SETUPX.@)
386 INT16 WINAPI VcpEnumFiles(VCPENUMPROC vep, LPARAM lParamRef)
390 for (n = 0; n < vn_last; n++)
391 vep(pvnlist[n], lParamRef);
393 return 0; /* FIXME: return value ? */
396 /***********************************************************************
397 * VcpExplain (SETUPX.411)
399 LPCSTR WINAPI VcpExplain16(LPVIRTNODE lpVn, DWORD dwWhat)
401 static char buffer[MAX_PATH]; /* FIXME: is this how it's done ? */
408 LPVCPFILESPEC lpvfs =
409 (dwWhat == VCPEX_SRC_FULL) ? &lpVn->vfsSrc : &lpVn->vfsDst;
411 /* if we have an ldid, use it, otherwise use the string */
412 /* from the vhstrlist array */
413 if (lpvfs->ldid != 0xffff)
414 CtlGetLddPath16(lpvfs->ldid, buffer);
416 strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrDir));
418 strcat(buffer, "\\");
419 strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrFileName));
423 FIXME("%ld unimplemented !\n", dwWhat);
424 strcpy(buffer, "Unknown error");
430 RETERR16 VCP_CheckPaths(void)
436 cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATPATHCHECKSTART, 0, 0, VCP_MsgRef);
437 for (n = 0; n < vn_num; n++)
441 /* FIXME: check paths of all VIRTNODEs here ! */
442 cbres = VCP_CALLBACK(&lpvn->vfsDst, VCPM_CHECKPATH, 0, (DWORD)lpvn, VCP_MsgRef);
444 cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATPATHCHECKEND, 0, 0, VCP_MsgRef);
448 RETERR16 VCP_CopyFiles(void)
450 char fn_src[MAX_PATH], fn_dst[MAX_PATH];
451 RETERR16 res = OK, cbres;
455 cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATCOPYSTART, 0, 0, VCP_MsgRef);
456 for (n = 0; n < vn_num; n++)
459 if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_COPY)) continue;
460 /* FIXME: need to send VCPM_VSTATNEWDISK notification sometimes */
461 strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));
462 strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));
463 /* FIXME: what is this VCPM_VSTATWRITE here for ?
464 * I guess it's to signal successful destination file creation */
465 cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);
467 /* FIXME: need to do the file copy in small chunks for notifications */
468 TRACE("copying '%s' to '%s'\n", fn_src, fn_dst);
469 /* perform the file copy */
470 if (!(CopyFileA(fn_src, fn_dst,
471 (lpvn->fl & VNLP_COPYIFEXISTS) ? FALSE : TRUE )))
473 ERR("error copying, src: %s -> dst: %s\n", fn_src, fn_dst);
474 res = ERR_VCP_IOFAIL;
477 vcp_status.prgFileRead.dwSoFar++;
478 cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATREAD, 0, 0, VCP_MsgRef);
479 vcp_status.prgFileWrite.dwSoFar++;
480 cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);
483 cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATCOPYEND, 0, 0, VCP_MsgRef);
487 /***********************************************************************
488 * VcpFlush - internal (not exported), but documented
490 * VNFL_NOW is used for VcpFlush.
492 RETERR16 VcpFlush16(WORD fl, LPCSTR lpszBackupDest)
497 /***********************************************************************
498 * VcpClose (SETUPX.201)
500 * Does callbacks (-> vifproc) with VCPM_VSTATCLOSESTART,
501 * VCPM_VSTATCLOSEEND.
503 * fl gets VCPFL_xxx flags to indicate what to do with the
504 * VIRTNODEs (files to mess with) created by e.g. GenInstall()
506 RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest)
509 WORD cbres = VCPN_PROCEED;
511 TRACE("(%04x, '%s')\n", fl, lpszBackupDest);
513 /* FIXME: needs to sort virtnodes in case VCPFL_INSPECIFIEDORDER
514 * is not set. This is done by VCP_CALLBACK(VCPM_NODECOMPARE) */
517 memset(&vcp_status, 0, sizeof(VCPSTATUS));
518 /* yes, vcp_status.cbSize is 0 ! */
520 cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATCLOSESTART, 0, 0, VCP_MsgRef);
523 res = VCP_CheckPaths();
526 return res; /* is this ok ? */
530 cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATCLOSEEND, 0, 0, VCP_MsgRef);
533 FreeLibrary(SETUPAPI_hInstance);
538 RETERR16 VCP_RenameFiles(void)
540 char fn_src[MAX_PATH], fn_dst[MAX_PATH];
541 RETERR16 res = OK, cbres;
545 cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATRENAMESTART, 0, 0, VCP_MsgRef);
546 for (n = 0; n < vn_num; n++)
549 if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_RENAME)) continue;
550 strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));
551 strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));
552 cbres = VCP_CALLBACK(&lpvn->vfsDst, VCPM_FILEOPENOUT, 0, (LPARAM)lpvn, VCP_MsgRef);
553 if (!(MoveFileExA(fn_src, fn_dst, MOVEFILE_REPLACE_EXISTING)))
554 res = ERR_VCP_IOFAIL;
556 VCP_VirtnodeDelete(lpvn);
558 cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATRENAMEEND, 0, 0, VCP_MsgRef);
562 /***********************************************************************
563 * vcpDefCallbackProc (SETUPX.202)
565 RETERR16 WINAPI vcpDefCallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
566 LPARAM lParam, LPARAM lParamRef)
568 static int count = 0;
570 FIXME("(%p, %04x, %04x, %08lx, %08lx) - what to do here ?\n",
571 lpvObj, uMsg, wParam, lParam, lParamRef);
576 /********************* point-and-click stuff from here ***********************/
578 static HWND hDlgCopy = 0;
579 static HKEY hKeyFiles = 0, hKeyRename = 0, hKeyConflict = 0;
580 static char BackupDir[12];
582 static INT_PTR CALLBACK VCP_UI_FileCopyDlgProc(HWND hWndDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
584 INT_PTR retval = FALSE;
586 if (iMsg == WM_INITDIALOG)
588 ShowWindow(hWndDlg, SW_SHOWNORMAL);
589 UpdateWindow(hWndDlg);
595 BOOL VCP_UI_GetDialogTemplate(LPCVOID *template32)
600 if (!(hResInfo = FindResourceA(SETUPAPI_hInstance, MAKEINTRESOURCEA(COPYFILEDLGORD), RT_DIALOGA)))
602 if (!(hDlgTmpl32 = LoadResource(SETUPAPI_hInstance, hResInfo )) ||
603 !(*template32 = LockResource( hDlgTmpl32 )))
608 static LRESULT WINAPI
609 VCP_UI_FileCopyWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
611 if (uMsg != WM_CREATE)
612 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
619 FIXME("%04x: unhandled.\n", uMsg);
625 void VCP_UI_RegisterProgressClass(void)
627 static BOOL registered = FALSE;
634 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
635 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
636 wndClass.lpfnWndProc = (WNDPROC)VCP_UI_FileCopyWndProc;
637 wndClass.cbClsExtra = 0;
638 wndClass.cbWndExtra = 0;
639 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
640 wndClass.hbrBackground = NULL;
641 wndClass.lpszClassName = "setupx_progress";
643 RegisterClassA (&wndClass);
646 RETERR16 VCP_UI_NodeCompare(LPVIRTNODE vn1, LPVIRTNODE vn2)
649 file1 = vsmGetStringRawName16(vn1->vfsSrc.vhstrFileName);
650 file2 = vsmGetStringRawName16(vn2->vfsSrc.vhstrFileName);
651 return (RETERR16)strcmp(file1, file2);
654 RETERR16 VCP_UI_CopyStart(void)
657 char buf[256]; /* plenty */
661 /* FIXME: should be registered at DLL startup instead */
662 VCP_UI_RegisterProgressClass();
663 if (!(VCP_UI_GetDialogTemplate(&template32)))
666 if (vn_num > 10) /* hack */
668 hDlgCopy = CreateDialogIndirectParamA(SETUPAPI_hInstance, template32, 0,
669 VCP_UI_FileCopyDlgProc, 0);
672 SetDlgItemTextA(hDlgCopy, SOURCESTRORD, "Scanning ...");
673 SetDlgItemTextA(hDlgCopy, DESTSTRORD, "NOT_IMPLEMENTED_YET");
675 strcpy(buf, REG_INSTALLEDFILES);
676 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyFiles))
678 strcat(buf, REGPART_RENAME);
679 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyRename))
681 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT, &hKeyConflict))
684 if (!(RegQueryValueExA(hKeyConflict, "Dirty", NULL, 0, (LPBYTE)&dirty, &len)))
686 /* FIXME: what does SETUPX.DLL do in this case ? */
687 MESSAGE("Warning: another program using SETUPX is already running ! Failed.\n");
691 if (RegSetValueExA(hKeyConflict, "Dirty", 0, REG_BINARY, (LPBYTE)&dirty, 1))
694 if (!(RegQueryValueExA(hKeyConflict, "BackupDirectory", NULL, 0, BackupDir, &len)))
695 strcpy(BackupDir, "VCM");
697 /* create C:\WINDOWS\[BackupDir] and set registry key to it */
698 GetWindowsDirectoryA(buf, 256);
700 strcat(buf, BackupDir);
701 if (!(CreateDirectoryA(buf, NULL)))
703 if (RegSetValueExA(hKeyConflict, "BackupDirectory", 0, REG_SZ, (LPBYTE)buf, strlen(buf)+1))
705 RegCloseKey(hKeyConflict);
710 /***********************************************************************
711 * vcpUICallbackProc (SETUPX.213)
713 RETERR16 WINAPI vcpUICallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
714 LPARAM lParam, LPARAM lParamRef)
716 static int count = 0;
717 RETERR16 res = VCPN_OK, cbres;
720 FIXME("(%p, %04x, %04x, %08lx, %08lx) - semi-stub\n",
721 lpvObj, uMsg, wParam, lParam, lParamRef);
725 /* unused messages, it seems */
726 case VCPM_DISKPREPINFO:
728 case VCPM_FILENEEDED:
730 case VCPM_NODECREATE:
731 case VCPM_NODEACCEPT:
733 case VCPM_VSTATCLOSESTART:
734 case VCPM_VSTATPATHCHECKSTART:
735 case VCPM_VSTATPATHCHECKEND:
741 case VCPM_NODECOMPARE:
742 res = VCP_UI_NodeCompare((LPVIRTNODE)lpvObj, (LPVIRTNODE)lParam);
746 case VCPM_VSTATWRITE:
747 cbres = VCP_CALLBACK(&vcp_status, VCPM_DISKPREPINFO, 0, 0, VCP_MsgRef);
749 case VCPM_VSTATCLOSEEND:
750 RegCloseKey(hKeyFiles);
751 RegCloseKey(hKeyRename);
752 RegDeleteKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT);
754 case VCPM_VSTATCOPYSTART:
755 res = VCP_UI_CopyStart();
757 case VCPM_VSTATCOPYEND:
758 if (hDlgCopy) DestroyWindow(hDlgCopy);
761 FIXME("unhandled msg 0x%04x\n", uMsg);