setupapi: Remove some dead code: VCP_VirtnodeDelete() and VCP_RenameFiles().
[wine/wine-gecko.git] / dlls / setupapi / virtcopy.c
blob435f2d916417486fd22c2748550ea5dc1138a104
1 /*
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.
24 #include <stdarg.h>
25 #include <string.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winreg.h"
30 #include "wownt32.h"
31 #include "winnls.h"
32 #include "setupapi.h"
33 #include "setupx16.h"
34 #include "setupapi_private.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
39 static FARPROC16 VCP_Proc = NULL;
40 static LPARAM VCP_MsgRef = 0;
42 static BOOL VCP_opened = FALSE;
44 static VCPSTATUS vcp_status;
46 static WORD VCP_Callback( LPVOID obj, UINT16 msg, WPARAM16 wParam, LPARAM lParam, LPARAM lParamRef )
48 WORD args[8];
49 DWORD ret = OK;
50 if (VCP_Proc)
52 args[7] = HIWORD(obj);
53 args[6] = LOWORD(obj);
54 args[5] = msg;
55 args[4] = wParam;
56 args[3] = HIWORD(lParam);
57 args[2] = LOWORD(lParam);
58 args[1] = HIWORD(lParamRef);
59 args[0] = LOWORD(lParamRef);
60 WOWCallback16Ex( (DWORD)VCP_Proc, WCB16_PASCAL, sizeof(args), args, &ret );
62 return (WORD)ret;
65 /****************************** VHSTR management ******************************/
68 * This is a totally braindead implementation for now;
69 * I don't care about speed at all ! Size and implementation time
70 * is much more important IMHO. I could have created some sophisticated
71 * tree structure, but... what the hell ! :-)
73 typedef struct {
74 DWORD refcount;
75 LPCSTR pStr;
76 } VHSTR_STRUCT;
78 static VHSTR_STRUCT **vhstrlist = NULL;
79 static VHSTR vhstr_alloc = 0;
81 #define VALID_VHSTR(x) ((x < vhstr_alloc) && (vhstrlist[x]) && (vhstrlist[x]->refcount))
83 /***********************************************************************
84 * vsmStringAdd (SETUPX.207)
86 VHSTR WINAPI vsmStringAdd16(LPCSTR lpszName)
88 VHSTR n;
89 VHSTR index = 0xffff;
90 HANDLE heap;
91 LPSTR str;
93 TRACE("add string '%s'\n", lpszName);
94 /* search whether string already inserted */
95 TRACE("searching for existing string...\n");
96 for (n = 0; n < vhstr_alloc; n++)
98 if ((vhstrlist[n]) && (vhstrlist[n]->refcount))
100 TRACE("checking item: %d\n", n);
101 if (!strcmp(vhstrlist[n]->pStr, lpszName))
103 TRACE("found\n");
104 vhstrlist[n]->refcount++;
105 return n;
110 /* hmm, not found yet, let's insert it */
111 TRACE("inserting item\n");
112 for (n = 0; n < vhstr_alloc; n++)
114 if ((!(vhstrlist[n])) || (!(vhstrlist[n]->refcount)))
116 index = n;
117 break;
120 heap = GetProcessHeap();
121 if (n == vhstr_alloc) /* hmm, no free index found yet */
123 index = vhstr_alloc;
124 vhstr_alloc += 20;
126 if (vhstrlist)
127 vhstrlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, vhstrlist,
128 sizeof(VHSTR_STRUCT *) * vhstr_alloc);
129 else
130 vhstrlist = HeapAlloc(heap, HEAP_ZERO_MEMORY,
131 sizeof(VHSTR_STRUCT *) * vhstr_alloc);
133 if (index == 0xffff)
134 return 0xffff; /* failure */
135 if (!vhstrlist[index])
136 vhstrlist[index] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VHSTR_STRUCT));
137 vhstrlist[index]->refcount = 1;
138 str = HeapAlloc(heap, 0, strlen(lpszName)+1);
139 strcpy(str, lpszName);
140 vhstrlist[index]->pStr = str;
141 return index;
144 /***********************************************************************
145 * vsmStringDelete (SETUPX.206)
147 INT16 WINAPI vsmStringDelete16(VHSTR vhstr)
149 if (VALID_VHSTR(vhstr))
151 vhstrlist[vhstr]->refcount--;
152 if (!vhstrlist[vhstr]->refcount)
154 HeapFree(GetProcessHeap(), 0, (LPSTR)vhstrlist[vhstr]->pStr);
155 vhstrlist[vhstr]->pStr = NULL;
157 return VCPN_OK;
160 /* string not found */
161 return VCPN_FAIL;
165 * vsmStringFind() - not exported from a standard SETUPX.DLL, it seems
167 VHSTR WINAPI vsmStringFind16(LPCSTR lpszName)
169 WORD n;
170 for (n = 0; n < vhstr_alloc; n++)
171 if ((vhstrlist[n]) && (vhstrlist[n]->refcount) && (!strcmp(vhstrlist[n]->pStr, lpszName)))
172 return n;
173 return 0xffff;
176 /***********************************************************************
177 * vsmGetStringName (SETUPX.205)
179 * Pretty correct, I guess
181 INT16 WINAPI vsmGetStringName16(VHSTR vhstr, LPSTR lpszBuffer, int cbBuffer)
183 if (VALID_VHSTR(vhstr))
185 int len = strlen(vhstrlist[vhstr]->pStr)+1;
186 if (cbBuffer >= len)
188 if (lpszBuffer)
189 strcpy(lpszBuffer, vhstrlist[vhstr]->pStr);
190 return len;
193 return VCPN_FAIL;
196 /***********************************************************************
197 * vsmStringCompare (not exported from a standard SETUPX.DLL, it seems)
199 INT16 WINAPI vsmStringCompare16(VHSTR vhstrA, VHSTR vhstrB)
201 if ((!VALID_VHSTR(vhstrA)) || (!VALID_VHSTR(vhstrB)))
202 return VCPN_FAIL; /* correct ? */
203 return strcmp(vhstrlist[vhstrA]->pStr, vhstrlist[vhstrB]->pStr);
206 /***********************************************************************
207 * vsmGetStringRawName (SETUPX.208)
209 LPCSTR WINAPI vsmGetStringRawName16(VHSTR vhstr)
211 return (VALID_VHSTR(vhstr)) ? vhstrlist[vhstr]->pStr : NULL;
215 /***************************** VIRTNODE management ****************************/
216 static LPVIRTNODE *pvnlist = NULL;
217 static DWORD vn_num = 0;
218 static DWORD vn_last = 0;
220 static RETERR16 VCP_VirtnodeCreate(const VCPFILESPEC *vfsSrc, const VCPFILESPEC *vfsDst,
221 WORD fl, LPARAM lParam, LPEXPANDVTBL lpExpandVtbl)
223 HANDLE heap;
224 LPVIRTNODE lpvn;
225 RETERR16 cbres;
227 while (vn_last < vn_num)
229 if (pvnlist[vn_last] == NULL)
230 break;
231 vn_last++;
233 heap = GetProcessHeap();
234 if (vn_last == vn_num)
236 vn_num += 20;
237 if (pvnlist)
238 pvnlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, pvnlist,
239 sizeof(LPVIRTNODE *) * vn_num);
240 else
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];
246 vn_last++;
248 lpvn->cbSize = sizeof(VIRTNODE);
250 if (vfsSrc)
251 lpvn->vfsSrc = *vfsSrc;
253 if (vfsDst)
254 lpvn->vfsDst = *vfsDst;
256 lpvn->fl = fl;
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);
266 return OK;
269 /***********************************************************************
270 * VcpOpen (SETUPX.200)
272 * Sets up a virtual copy operation.
273 * This means that functions such as GenInstall()
274 * create a VIRTNODE struct for every file to be touched in a .INF file
275 * instead of actually touching the file.
276 * The actual copy/move/rename gets started when VcpClose or
277 * VcpFlush is called; several different callbacks are made
278 * (copy, rename, open, close, version conflicts, ...) on every file copied.
280 RETERR16 WINAPI VcpOpen16(VIFPROC vifproc, LPARAM lparamMsgRef)
282 TRACE("(%p, %08lx)\n", vifproc, lparamMsgRef);
283 if (VCP_opened)
284 return ERR_VCP_BUSY;
286 VCP_Proc = (FARPROC16)vifproc;
287 VCP_MsgRef = lparamMsgRef;
289 VCP_opened = TRUE;
290 return OK;
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;
310 if (!VCP_opened)
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,
327 lpExpandVtbl);
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,
338 LPCSTR lpszDstDir,
339 LOGDISKID16 ldidDst,
340 LPARAM lParamRef
343 VCPFILESPEC vfsDst;
345 if (!VCP_opened)
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,
363 LPARAM lParam
366 VCPFILESPEC vfsSrc, vfsDst;
368 if (!VCP_opened)
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)
388 WORD n;
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 ? */
402 buffer[0] = '\0';
403 switch (dwWhat)
405 case VCPEX_SRC_FULL:
406 case VCPEX_DST_FULL:
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);
415 else
416 strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrDir));
418 strcat(buffer, "\\");
419 strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrFileName));
421 break;
422 default:
423 FIXME("%d unimplemented !\n", dwWhat);
424 strcpy(buffer, "Unknown error");
425 break;
427 return buffer;
430 static RETERR16 VCP_CheckPaths(void)
432 DWORD n;
433 LPVIRTNODE lpvn;
434 RETERR16 cbres;
436 cbres = VCP_Callback(&vcp_status, VCPM_VSTATPATHCHECKSTART, 0, 0, VCP_MsgRef);
437 for (n = 0; n < vn_num; n++)
439 lpvn = pvnlist[n];
440 if (!lpvn) continue;
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);
445 return OK;
448 static RETERR16 VCP_CopyFiles(void)
450 char fn_src[MAX_PATH], fn_dst[MAX_PATH];
451 RETERR16 res = OK, cbres;
452 DWORD n;
453 LPVIRTNODE lpvn;
455 cbres = VCP_Callback(&vcp_status, VCPM_VSTATCOPYSTART, 0, 0, VCP_MsgRef);
456 for (n = 0; n < vn_num; n++)
458 lpvn = pvnlist[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);
484 return res;
487 /***********************************************************************
488 * VcpFlush - internal (not exported), but documented
490 * VNFL_NOW is used for VcpFlush.
492 RETERR16 VcpFlush16(WORD fl, LPCSTR lpszBackupDest)
494 return OK;
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)
508 RETERR16 res = OK;
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) */
516 TRACE("#1\n");
517 memset(&vcp_status, 0, sizeof(VCPSTATUS));
518 /* yes, vcp_status.cbSize is 0 ! */
519 TRACE("#2\n");
520 cbres = VCP_Callback(&vcp_status, VCPM_VSTATCLOSESTART, 0, 0, VCP_MsgRef);
521 TRACE("#3\n");
523 res = VCP_CheckPaths();
524 TRACE("#4\n");
525 if (res != OK)
526 return res; /* is this ok ? */
527 VCP_CopyFiles();
529 TRACE("#5\n");
530 cbres = VCP_Callback(&vcp_status, VCPM_VSTATCLOSEEND, 0, 0, VCP_MsgRef);
531 TRACE("#6\n");
532 VCP_Proc = NULL;
533 VCP_opened = FALSE;
534 return OK;
537 /***********************************************************************
538 * vcpDefCallbackProc (SETUPX.202)
540 RETERR16 WINAPI vcpDefCallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
541 LPARAM lParam, LPARAM lParamRef)
543 static int count = 0;
544 if (count < 10)
545 FIXME("(%p, %04x, %04lx, %08lx, %08lx) - what to do here ?\n",
546 lpvObj, uMsg, wParam, lParam, lParamRef);
547 count++;
548 return OK;
551 /********************* point-and-click stuff from here ***********************/
553 static HWND hDlgCopy = 0;
554 static HKEY hKeyFiles = 0, hKeyRename = 0, hKeyConflict = 0;
555 static char BackupDir[12];
557 static INT_PTR CALLBACK VCP_UI_FileCopyDlgProc(HWND hWndDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
559 INT_PTR retval = FALSE;
561 if (iMsg == WM_INITDIALOG)
563 ShowWindow(hWndDlg, SW_SHOWNORMAL);
564 UpdateWindow(hWndDlg);
565 retval = TRUE;
567 return retval;
570 static BOOL VCP_UI_GetDialogTemplate(LPCVOID *template32)
572 HRSRC hResInfo;
573 HGLOBAL hDlgTmpl32;
575 if (!(hResInfo = FindResourceA(SETUPAPI_hInstance, MAKEINTRESOURCEA(COPYFILEDLGORD), (LPSTR)RT_DIALOG)))
576 return FALSE;
577 if (!(hDlgTmpl32 = LoadResource(SETUPAPI_hInstance, hResInfo )) ||
578 !(*template32 = LockResource( hDlgTmpl32 )))
579 return FALSE;
580 return TRUE;
583 static LRESULT WINAPI
584 VCP_UI_FileCopyWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
586 if (uMsg != WM_CREATE)
587 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
589 switch (uMsg)
591 case WM_CREATE:
592 return 0;
593 default:
594 FIXME("%04x: unhandled.\n", uMsg);
597 return 0;
600 static void VCP_UI_RegisterProgressClass(void)
602 static BOOL registered = FALSE;
603 WNDCLASSA wndClass;
605 if (registered)
606 return;
608 registered = TRUE;
609 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
610 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
611 wndClass.lpfnWndProc = VCP_UI_FileCopyWndProc;
612 wndClass.cbClsExtra = 0;
613 wndClass.cbWndExtra = 0;
614 wndClass.hCursor = LoadCursorA (0, (LPSTR)IDC_ARROW);
615 wndClass.hbrBackground = NULL;
616 wndClass.lpszClassName = "setupx_progress";
618 RegisterClassA (&wndClass);
621 static RETERR16 VCP_UI_NodeCompare(LPVIRTNODE vn1, LPVIRTNODE vn2)
623 LPCSTR file1, file2;
624 file1 = vsmGetStringRawName16(vn1->vfsSrc.vhstrFileName);
625 file2 = vsmGetStringRawName16(vn2->vfsSrc.vhstrFileName);
626 return (RETERR16)strcmp(file1, file2);
629 static RETERR16 VCP_UI_CopyStart(void)
631 LPCVOID template32;
632 char buf[256]; /* plenty */
633 BOOL dirty;
634 DWORD len;
636 /* FIXME: should be registered at DLL startup instead */
637 VCP_UI_RegisterProgressClass();
638 if (!(VCP_UI_GetDialogTemplate(&template32)))
639 return VCPN_FAIL;
641 if (vn_num > 10) /* hack */
643 hDlgCopy = CreateDialogIndirectParamA(SETUPAPI_hInstance, template32, 0,
644 VCP_UI_FileCopyDlgProc, 0);
645 if (!hDlgCopy)
646 return VCPN_FAIL;
647 SetDlgItemTextA(hDlgCopy, SOURCESTRORD, "Scanning ...");
648 SetDlgItemTextA(hDlgCopy, DESTSTRORD, "NOT_IMPLEMENTED_YET");
650 strcpy(buf, REG_INSTALLEDFILES);
651 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyFiles))
652 return VCPN_FAIL;
653 strcat(buf, REGPART_RENAME);
654 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyRename))
655 return VCPN_FAIL;
656 if (RegCreateKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT, &hKeyConflict))
657 return VCPN_FAIL;
658 len = 1;
659 if (!(RegQueryValueExA(hKeyConflict, "Dirty", NULL, 0, (LPBYTE)&dirty, &len)))
661 /* FIXME: what does SETUPX.DLL do in this case ? */
662 MESSAGE("Warning: another program using SETUPX is already running ! Failed.\n");
663 return VCPN_FAIL;
665 dirty = TRUE;
666 if (RegSetValueExA(hKeyConflict, "Dirty", 0, REG_BINARY, (LPBYTE)&dirty, 1))
667 return VCPN_FAIL;
668 len = 12;
669 if (!(RegQueryValueExA(hKeyConflict, "BackupDirectory", NULL, 0, (LPBYTE)BackupDir, &len)))
670 strcpy(BackupDir, "VCM");
672 /* create C:\WINDOWS\[BackupDir] and set registry key to it */
673 GetWindowsDirectoryA(buf, 256);
674 strcat(buf, "\\");
675 strcat(buf, BackupDir);
676 if (!(CreateDirectoryA(buf, NULL)))
677 return VCPN_FAIL;
678 if (RegSetValueExA(hKeyConflict, "BackupDirectory", 0, REG_SZ, (LPBYTE)buf, strlen(buf)+1))
679 return VCPN_FAIL;
680 RegCloseKey(hKeyConflict);
682 return VCPN_OK;
685 /***********************************************************************
686 * vcpUICallbackProc (SETUPX.213)
688 RETERR16 WINAPI vcpUICallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
689 LPARAM lParam, LPARAM lParamRef)
691 static int count = 0;
692 RETERR16 res = VCPN_OK, cbres;
694 if (count < 5)
695 FIXME("(%p, %04x, %04lx, %08lx, %08lx) - semi-stub\n",
696 lpvObj, uMsg, wParam, lParam, lParamRef);
697 count++;
698 switch (uMsg)
700 /* unused messages, it seems */
701 case VCPM_DISKPREPINFO:
703 case VCPM_FILENEEDED:
705 case VCPM_NODECREATE:
706 case VCPM_NODEACCEPT:
708 case VCPM_VSTATCLOSESTART:
709 case VCPM_VSTATPATHCHECKSTART:
710 case VCPM_VSTATPATHCHECKEND:
712 case VCPM_CHECKPATH:
713 break;
715 /* the real stuff */
716 case VCPM_NODECOMPARE:
717 res = VCP_UI_NodeCompare((LPVIRTNODE)lpvObj, (LPVIRTNODE)lParam);
718 break;
719 case VCPM_VSTATREAD:
720 break;
721 case VCPM_VSTATWRITE:
722 cbres = VCP_Callback(&vcp_status, VCPM_DISKPREPINFO, 0, 0, VCP_MsgRef);
723 break;
724 case VCPM_VSTATCLOSEEND:
725 RegCloseKey(hKeyFiles);
726 RegCloseKey(hKeyRename);
727 RegDeleteKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT);
728 break;
729 case VCPM_VSTATCOPYSTART:
730 res = VCP_UI_CopyStart();
731 break;
732 case VCPM_VSTATCOPYEND:
733 if (hDlgCopy) DestroyWindow(hDlgCopy);
734 break;
735 default:
736 FIXME("unhandled msg 0x%04x\n", uMsg);
738 return res;