- implement some more virtcopy (VCP) stuff

- add some setupx resources
- implement VHSTR functionality
- large parts of VCP callback handling
- merge setupapi and setupx stuff, especially resource handling
  gets rid of setupx debug channel; setupapi is the only one that remains
This commit is contained in:
Andreas Mohr 2001-04-17 17:39:35 +00:00 committed by Alexandre Julliard
parent 793bf04e24
commit 9bebbc5d8e
10 changed files with 1140 additions and 63 deletions

View File

@ -1,3 +1,5 @@
Makefile
setupapi.res
setupapi.spec.c
setupx.spec.c
virtcopy.glue.c

View File

@ -13,7 +13,14 @@ C_SRCS = \
devinst.c \
infparse.c \
setupx_main.c \
stubs.c
stubs.c \
virtcopy.c
GLUE = \
virtcopy.c
RC_SRCS= \
setupapi.rc
@MAKE_DLL_RULES@

View File

@ -16,9 +16,9 @@
#include "heap.h"
#include "wine/winbase16.h"
#include "setupx16.h"
#include "setupx_private.h"
#include "setupapi_private.h"
DEFAULT_DEBUG_CHANNEL(setupx);
DEFAULT_DEBUG_CHANNEL(setupapi);
WORD InfNumEntries = 0;
INF_FILE *InfList = NULL;

34
dlls/setupapi/setupapi.rc Normal file
View File

@ -0,0 +1,34 @@
/*
* Top level resource file for SETUPX
*
*/
#include "windef.h"
#include "winuser.h"
#include "winnls.h"
#include "setupapi_private.h"
/*--------------------- FIXME --------------------------
*
* These must be seperated into the language files
* and translated. The language 0,0 is a hack to get it
* loaded properly for all languages by pretending that
* they are neutral.
* The menus are not yet properly implemented.
* Don't localize it yet. (js)
*/
LANGUAGE 0,0
COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105
STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION
CAPTION "Copying Files..."
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Cancel", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
LTEXT "Source:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
LTEXT "Destination:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP
CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
END

View File

@ -1,11 +1,13 @@
name setupapi
type win32
rsrc setupapi.res
import user32.dll
import advapi32.dll
import kernel32.dll
import ntdll.dll
debug_channels (setupapi setupx)
debug_channels (setupapi)
# almost all functions are commented out for now. Ordinals are from setupapi.dll 4.0

View File

@ -1,8 +1,18 @@
#ifndef __SETUPX_PRIVATE_H
#define __SETUPX_PRIVATE_H
#ifndef __SETUPAPI_PRIVATE_H
#define __SETUPAPI_PRIVATE_H
#include "wine/windef16.h"
#define COPYFILEDLGORD 1000
#define SOURCESTRORD 500
#define DESTSTRORD 501
#define PROGRESSORD 502
#define REG_INSTALLEDFILES "System\\CurrentControlSet\\Control\\InstalledFiles"
#define REGPART_RENAME "\\Rename"
#define REG_VERSIONCONFLICT "Software\\Microsoft\\VersionConflictManager"
typedef struct tagLDD_LIST {
LPLOGDISKDESC pldd;
struct tagLDD_LIST *next;
@ -26,4 +36,4 @@ extern WORD InfNumEntries;
extern LPCSTR IP_GetFileName(HINF16 hInf);
#endif /* __SETUPX_PRIVATE_H */
#endif /* __SETUPAPI_PRIVATE_H */

View File

@ -14,11 +14,11 @@ owner setupapi
10 stub IpGetIntField #(word ptr word ptr)
11 stub IpFindNextLine #(word ptr)
12 stub IpGetFileName #(word ptr word)
13 stub VcpQueueCopy #(str str str str word word ptr word long)
13 pascal16 VcpQueueCopy(str str str str word word ptr word long) VcpQueueCopy16
14 stub NOAUTORUNWNDPROC
15 stub __DEBUGMSG
16 stub __ASSERTMSG
17 stub VcpQueueDelete #(str str word long)
17 pascal16 VcpQueueDelete(str str word long) VcpQueueDelete16
18 stub TpOpenFile #(str ptr word)
19 stub TpCloseFile #(word)
20 stub TpOpenSection #(word ptr str word)
@ -62,6 +62,7 @@ owner setupapi
61 stub suErrorToIds #(word word)
62 stub TPWriteProfileString #(str str str)
63 stub SURPLSETUP
# does SUSTORELDIDPATH set the path of an LDID in the registry ?
64 stub SUSTORELDIDPATH
65 stub WILDCARDSTRCMPI
101 pascal16 GenInstall(word str word) GenInstall16
@ -122,20 +123,20 @@ owner setupapi
160 stub SXUPDATEDS
170 stub SUSETMEM
171 stub WriteDMFBootData #(word ptr word)
200 pascal VcpOpen(ptr str) VcpOpen16
200 pascal VcpOpen(segptr ptr) VcpOpen16
201 pascal VcpClose(word str) VcpClose16
202 stub vcpDefCallbackProc #(ptr word word long long)
202 pascal16 vcpDefCallbackProc(ptr word word long long) vcpDefCallbackProc16
203 stub vcpEnumFiles #(ptr long)
204 stub VcpQueueRename #(str str str str word word long)
205 stub vsmGetStringName #(word ptr word)
206 stub vsmStringDelete #(word)
207 stub vsmStringAdd #(str)
208 stub vsmGetStringRawName #(word)
204 pascal16 VcpQueueRename(str str str str word word long) VcpQueueRename16
205 pascal16 vsmGetStringName(word ptr word) vsmGetStringName16
206 pascal16 vsmStringDelete(word) vsmStringDelete16
207 pascal16 vsmStringAdd(str) vsmStringAdd16
208 pascal vsmGetStringRawName(word) vsmGetStringRawName16
209 stub IpSaveRestorePosition #(word word)
210 pascal16 IpGetProfileString(word str str ptr word) IpGetProfileString16
211 stub IpOpenEx #(str ptr word)
212 stub IpOpenAppendEx #(str word word)
213 stub vcpUICallbackProc #(ptr word word long long)
213 pascal16 vcpUICallbackProc(ptr word word long long) vcpUICallbackProc16
214 stub VcpAddMRUPath #(str)
300 stub DiBuildCompatDrvList #(ptr)
301 stub DiBuildClassDrvList #(ptr)

View File

@ -5,6 +5,7 @@
typedef UINT16 HINF16;
typedef UINT16 LOGDISKID16;
typedef UINT16 VHSTR;
#define LINE_LEN 256
@ -18,7 +19,7 @@ typedef UINT16 RETERR16;
#define GEN_ERROR (UINT16)400
#define DI_ERROR (UINT16)500
enum _IP_ERR {
enum {
ERR_IP_INVALID_FILENAME = IP_ERROR+1,
ERR_IP_ALLOC_ERR,
ERR_IP_INVALID_SECT_NAME,
@ -37,7 +38,113 @@ enum _IP_ERR {
ERR_IP_INVALID_INFTYPE
};
enum _ERR_VCP {
/****** virtual copy operations ******/
typedef DWORD LPEXPANDVTBL;
typedef struct {
DWORD dwSoFar;
DWORD dwTotal;
} VCPPROGRESS, *LPVCPPROGRESS;
typedef struct {
WORD cbSize;
LOGDISKID16 ldid;
VHSTR vhstrRoot;
VHSTR vhstrVolumeLabel;
VHSTR vhstrDiskName;
WORD wVolumeTime;
WORD wVolumeDate;
DWORD dwSerialNumber;
WORD fl;
LPARAM lparamRef;
VCPPROGRESS prgFileRead;
VCPPROGRESS prgByteRead;
VCPPROGRESS prgFileWrite;
VCPPROGRESS prgByteWrite;
} VCPDISKINFO, *LPVCPDISKINFO;
typedef struct {
LOGDISKID16 ldid;
VHSTR vhstrDir;
VHSTR vhstrFileName;
} VCPFILESPEC, *LPVCPFILESPEC;
typedef struct {
UINT16 uiMDate;
UINT16 uiMTime;
UINT16 uiADate;
UINT16 uiATime;
UINT16 uiAttr;
DWORD llenIn;
DWORD llenOut;
} VCPFATTR, *LPVCPFATTR;
typedef struct {
UINT16 uDate;
UINT16 uTime;
DWORD dwSize;
} VCPFILESTAT, *LPVCPFILESTAT;
typedef struct
{
HFILE16 hFileSrc;
HFILE16 hFileDst;
VCPFATTR fAttr;
WORD dosError;
VHSTR vhstrFileName;
WPARAM vcpm;
} VIRTNODEEX, *LPVIRTNODEEX;
typedef struct {
WORD cbSize;
VCPFILESPEC vfsSrc;
VCPFILESPEC vfsDst;
WORD fl;
LPARAM lParam;
LPEXPANDVTBL lpExpandVtbl;
LPVIRTNODEEX lpvnex;
VHSTR vhstrDstFinalName;
VCPFILESTAT vFileStat;
} VIRTNODE, *LPVIRTNODE;
typedef struct {
WORD cbSize;
VCPPROGRESS prgDiskRead;
VCPPROGRESS prgFileRead;
VCPPROGRESS prgByteRead;
VCPPROGRESS prgDiskWrite;
VCPPROGRESS prgFileWrite;
VCPPROGRESS prgByteWrite;
LPVCPDISKINFO lpvdiIn;
LPVCPDISKINFO lpvdiOut;
LPVIRTNODE lpvn;
} VCPSTATUS, *LPVCPSTATUS;
#define CNFL_BACKUP 0x0001
#define CNFL_DELETEONFAILURE 0x0002
#define CNFL_RENAMEONSUCCESS 0x0004
#define CNFL_CONTINUATION 0x0008
#define CNFL_SKIPPED 0x0010
#define CNFL_IGNOREERRORS 0x0020
#define CNFL_RETRYFILE 0x0040
#define CNFL_COPIED 0x0080
#define VNFL_UNIQUE 0x0000
#define VNFL_MULTIPLEOK 0x0100
#define VNFL_DESTROYOLD 0x0200
#define VNFL_COPY 0x0000
#define VNFL_DELETE 0x0800
#define VNFL_RENAME 0x1000
#define VNFL_NODE_TYPE (VNFL_RENAME|VNFL_DELETE|VNFL_COPY)
#define VNFL_CREATED 0x2000
#define VNFL_REJECTED 0x4000
#define VNFL_DEVICEINSTALLER 0x8000
enum {
ERR_VCP_IOFAIL = VCP_ERROR+1,
ERR_VCP_STRINGTOOLONG,
ERR_VCP_NOMEM,
@ -65,6 +172,205 @@ enum _ERR_VCP {
ERR_VCP_NO_DIGITAL_SIGNATURE_FILE
};
#define VCPN_OK 0
#define VCPN_PROCEED 0
#define VCPN_ABORT -1
#define VCPN_RETRY -2
#define VCPN_IGNORE -3
#define VCPN_SKIP -4
#define VCPN_FORCE -5
#define VCPN_DEFER -6
#define VCPN_FAIL -7
#define VCPN_RETRYFILE -8
#define VCPFL_ABANDON 0x00
#define VCPFL_BACKUP 0x01
#define VCPFL_COPY 0x02
#define VCPFL_BACKUPANDCOPY (VCPFL_BACKUP|VCPFL_COPY)
#define VCPFL_INSPECIFIEDORDER 0x04
#define VCPFL_DELETE 0x08
#define VCPFL_RENAME 0x10
#define VCPFL_ALL (VCPFL_COPY|VCPFL_DELETE|VCPFL_RENAME)
#define CFNL_BACKUP 0x0001
#define CFNL_DELETEONFAILURE 0x0002
#define CFNL_RENAMEONSUCCESS 0x0004
#define CFNL_CONTINUATION 0x0008
#define CFNL_SKIPPED 0x0010
#define CFNL_IGNOREERRORS 0x0020
#define CFNL_RETRYFILE 0x0040
#define CFNL_COPIED 0x0080
#define VFNL_MULTIPLEOK 0x0100
#define VFNL_DESTROYOLD 0x0200
#define VFNL_NOW 0x0400
#define VFNL_COPY 0x0000
#define VFNL_DELETE 0x0800
#define VFNL_RENAME 0x1000
#define VFNL_CREATED 0x2000
#define VFNL_REJECTED 0x4000
#define VCPM_DISKCLASS 0x01
#define VCPM_DISKFIRST 0x0100
#define VCPM_DISKLAST 0x01ff
enum {
VCPM_DISKCREATEINFO = VCPM_DISKFIRST,
VCPM_DISKGETINFO,
VCPM_DISKDESTROYINFO,
VCPM_DISKPREPINFO,
VCPM_DISKENSURE,
VCPM_DISKPROMPT,
VCPM_DISKFORMATBEGIN,
VCPM_DISKFORMATTING,
VCPM_DISKFORMATEND
};
#define VCPM_FILEINCLASS 0x02
#define VCPM_FILEOUTCLASS 0x03
#define VCPM_FILEFIRSTIN 0x0200
#define VCPM_FILEFIRSTOUT 0x0300
#define VCPM_FILELAST 0x03ff
enum {
VCPM_FILEOPENIN = VCPM_FILEFIRSTIN,
VCPM_FILEGETFATTR,
VCPM_FILECLOSEIN,
VCPM_FILECOPY,
VCPM_FILENEEDED,
VCPM_FILEOPENOUT = VCPM_FILEFIRSTOUT,
VCPM_FILESETFATTR,
VCPM_FILECLOSEOUT,
VCPM_FILEFINALIZE,
VCPM_FILEDELETE,
VCPM_FILERENAME
};
#define VCPM_NODECLASS 0x04
#define VCPM_NODEFIRST 0x0400
#define VCPM_NODELAST 0x04ff
enum {
VCPM_NODECREATE = VCPM_NODEFIRST,
VCPM_NODEACCEPT,
VCPM_NODEREJECT,
VCPM_NODEDESTROY,
VCPM_NODECHANGEDESTDIR,
VCPM_NODECOMPARE
};
#define VCPM_TALLYCLASS 0x05
#define VCPM_TALLYFIRST 0x0500
#define VCPM_TALLYLAST 0x05ff
enum {
VCPM_TALLYSTART = VCPM_TALLYFIRST,
VCPM_TALLYEND,
VCPM_TALLYFILE,
VCPM_TALLYDISK
};
#define VCPM_VERCLASS 0x06
#define VCPM_VERFIRST 0x0600
#define VCPM_VERLAST 0x06ff
enum {
VCPM_VERCHECK = VCPM_VERFIRST,
VCPM_VERCHECKDONE,
VCPM_VERRESOLVECONFLICT
};
#define VCPM_VSTATCLASS 0x07
#define VCPM_VSTATFIRST 0x0700
#define VCPM_VSTATLAST 0x07ff
enum {
VCPM_VSTATSTART = VCPM_VSTATFIRST,
VCPM_VSTATEND,
VCPM_VSTATREAD,
VCPM_VSTATWRITE,
VCPM_VSTATNEWDISK,
VCPM_VSTATCLOSESTART,
VCPM_VSTATCLOSEEND,
VCPM_VSTATBACKUPSTART,
VCPM_VSTATBACKUPEND,
VCPM_VSTATRENAMESTART,
VCPM_VSTATRENAMEEND,
VCPM_VSTATCOPYSTART,
VCPM_VSTATCOPYEND,
VCPM_VSTATDELETESTART,
VCPM_VSTATDELETEEND,
VCPM_VSTATPATHCHECKSTART,
VCPM_VSTATPATHCHECKEND,
VCPM_VSTATCERTIFYSTART,
VCPM_VSTATCERTIFYEND,
VCPM_VSTATUSERABORT,
VCPM_VSTATYIELD
};
#define VCPM_PATHCLASS 0x08
#define VCPM_PATHFIRST 0x0800
#define VCPM_PATHLAST 0x08ff
enum {
VCPM_BUILDPATH = VCPM_PATHFIRST,
VCPM_UNIQUEPATH,
VCPM_CHECKPATH
};
#define VCPM_PATCHCLASS 0x09
#define VCPM_PATCHFIRST 0x0900
#define VCPM_PATCHLAST 0x09ff
enum {
VCPM_FILEPATCHBEFORECPY = VCPM_PATCHFIRST,
VCPM_FILEPATCHAFTERCPY,
VCPM_FILEPATCHINFOPEN,
VCPM_FILEPATCHINFCLOSE
};
#define VCPM_CERTCLASS 0x0a
#define VCPM_CERTFIRST 0x0a00
#define VCPM_CERTLAST 0x0aff
enum {
VCPM_FILECERTIFY = VCPM_CERTFIRST,
VCPM_FILECERTIFYWARN
};
typedef LRESULT CALLBACK (*VIFPROC)(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam, LPARAM lParam, LPARAM lparamRef);
typedef int CALLBACK (*VCPENUMPROC)(LPVIRTNODE lpvn, LPARAM lparamRef);
RETERR16 WINAPI VcpOpen16(VIFPROC vifproc, LPARAM lparamMsgRef);
RETERR16 WINAPI VcpQueueCopy16(
LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
LPEXPANDVTBL lpExpandVtbl,
WORD fl, LPARAM lParam
);
RETERR16 VcpFlush16(WORD fl, LPCSTR lpszBackupDest);
RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest);
/* VcpExplain flags */
enum {
VCPEX_SRC_DISK,
VCPEX_SRC_CABINET,
VCPEX_SRC_LOCN,
VCPEX_DST_LOCN,
VCPEX_SRC_FILE,
VCPEX_DST_FILE,
VCPEX_DST_FILE_FINAL,
VCPEX_DOS_ERROR,
VCPEX_MESSAGE,
VCPEX_DOS_SOLUTION,
VCPEX_SRC_FULL,
VCPEX_DST_FULL,
VCPEX_DST_FULL_FINAL
};
LPCSTR WINAPI VcpExplain16(LPVIRTNODE lpVn, DWORD dwWhat);
/****** logical disk management ******/
typedef struct _LOGDISKDESC_S { /* ldd */
@ -198,8 +504,6 @@ typedef struct _DEVICE_INFO
} DEVICE_INFO16, *LPDEVICE_INFO16, **LPLPDEVICE_INFO16;
typedef LRESULT CALLBACK (*VIFPROC)(LPVOID lpvObj, UINT uMsg, WPARAM wParam, LPARAM lParam, LPARAM lparamRef);
extern void WINAPI GenFormStrWithoutPlaceHolders16(LPSTR,LPCSTR,HINF16);
extern RETERR16 WINAPI IpOpen16(LPCSTR,HINF16 *);
extern RETERR16 WINAPI IpClose16(HINF16);
@ -208,6 +512,7 @@ extern RETERR16 WINAPI CtlGetLdd16(LPLOGDISKDESC);
extern RETERR16 WINAPI CtlFindLdd16(LPLOGDISKDESC);
extern RETERR16 WINAPI CtlAddLdd16(LPLOGDISKDESC);
extern RETERR16 WINAPI CtlDelLdd16(LOGDISKID16);
extern RETERR16 WINAPI CtlGetLddPath16(LOGDISKID16 ldid, LPSTR szPath);
extern RETERR16 WINAPI GenInstall16(HINF16,LPCSTR,WORD);
#endif /* __SETUPX16_H */

View File

@ -47,12 +47,12 @@
#include "winreg.h"
#include "wine/winuser16.h"
#include "setupx16.h"
#include "setupx_private.h"
#include "setupapi_private.h"
#include "winerror.h"
#include "heap.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(setupx);
DEFAULT_DEBUG_CHANNEL(setupapi);
/***********************************************************************
* SURegOpenKey
@ -292,7 +292,7 @@ RETERR16 WINAPI InstallHinfSection16( HWND16 hwnd, HINSTANCE16 hinst, LPCSTR lps
LPSTR *pSub;
DWORD count;
HINF16 hInf = 0;
RETERR16 res = OK;
RETERR16 res = OK, tmp;
WORD wFlags;
BOOL reboot = FALSE;
HMODULE hMod;
@ -310,6 +310,8 @@ RETERR16 WINAPI InstallHinfSection16( HWND16 hwnd, HINSTANCE16 hinst, LPCSTR lps
res = ERROR_FILE_NOT_FOUND; /* yes, correct */
goto end;
}
if (VcpOpen16(NULL, 0))
goto end;
if (GenInstall16(hInf, *(pSub+count-2), GENINSTALL_DO_ALL) != OK)
goto end;
wFlags = atoi(*(pSub+count-1)) & ~128;
@ -338,7 +340,12 @@ RETERR16 WINAPI InstallHinfSection16( HWND16 hwnd, HINSTANCE16 hinst, LPCSTR lps
res = OK;
end:
IpClose16(hInf);
tmp = VcpClose16(VCPFL_ALL, NULL);
if (tmp != OK)
res = tmp;
tmp = IpClose16(hInf);
if (tmp != OK)
res = tmp;
SETUPX_FreeSubStrings(pSub);
if (reboot)
{
@ -502,7 +509,7 @@ static const LDID_DATA LDID_Data[34] =
* LDID == Logical Device ID
*
* The whole LDD/LDID business might go into a separate file named
* ldd.c or logdevice.c.
* ldd.c.
* At the moment I don't know what the hell these functions are really doing.
* That's why I added reporting stubs.
* The only thing I do know is that I need them for the LDD/LDID infrastructure.
@ -1048,28 +1055,6 @@ void WINAPI GenFormStrWithoutPlaceHolders16( LPSTR szDst, LPCSTR szSrc, HINF16 h
TRACE("ret '%s'\n", szDst);
}
/***********************************************************************
* VcpOpen
*
* No idea what to do here.
*/
RETERR16 WINAPI VcpOpen16(VIFPROC vifproc, LPARAM lparamMsgRef)
{
FIXME("(%p, %08lx), stub.\n", vifproc, lparamMsgRef);
return OK;
}
/***********************************************************************
* VcpClose
*
* Is fl related to VCPDISKINFO.fl ?
*/
RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest)
{
FIXME("(%04x, '%s'), stub.\n", fl, lpszBackupDest);
return OK;
}
/*
* Copy all items in a CopyFiles entry over to the destination
*
@ -1077,26 +1062,29 @@ RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest)
*/
static BOOL SETUPX_CopyFiles(LPSTR *pSub, HINF16 hInf)
{
BOOL res = FALSE;
BOOL bSingle = FALSE;
unsigned int n;
LPCSTR filename = IP_GetFileName(hInf);
LPSTR pCopyEntry;
char pDestStr[MAX_PATH];
char pDstStr[MAX_PATH];
LPSTR pSrcDir, pDstDir;
LPSTR pFileEntries, p;
WORD ldid;
LOGDISKDESC_S ldd;
LPSTR *pSubFile;
LPSTR pSrcFile, pDstFile;
WORD flag;
for (n=0; n < *(DWORD *)pSub; n++)
{
pCopyEntry = *(pSub+1+n);
if (*pCopyEntry == '@')
{
ERR("single file not handled yet !\n");
continue;
pCopyEntry++;
bSingle = TRUE;
}
else
bSingle = FALSE;
/* get source directory for that entry */
INIT_LDD(ldd, LDID_SRCPATH);
@ -1105,20 +1093,35 @@ static BOOL SETUPX_CopyFiles(LPSTR *pSub, HINF16 hInf)
/* get destination directory for that entry */
if (!(GetPrivateProfileStringA("DestinationDirs", pCopyEntry, "",
pDestStr, sizeof(pDestStr), filename)))
continue;
pDstStr, sizeof(pDstStr), filename)))
{
/* hmm, not found; try the default entry */
if (!(GetPrivateProfileStringA("DestinationDirs", "DefaultDestDir", "", pDstStr, sizeof(pDstStr), filename)))
{
WARN("DefaultDestDir not found.\n");
continue;
}
}
/* translate destination dir if given as LDID */
ldid = atoi(pDestStr);
ldid = atoi(pDstStr);
if (ldid)
{
if (!(SETUPX_IP_TranslateLDID(ldid, &pDstDir, hInf)))
continue;
}
else
pDstDir = pDestStr;
pDstDir = pDstStr;
/* now that we have the destination dir, iterate over files to copy */
/* now that we have the destination dir, register file copying */
if (bSingle)
{
VcpQueueCopy16(pCopyEntry, pCopyEntry, pSrcDir, pDstDir, LDID_SRCPATH, ldid ? ldid : 0xffff, 0, VFNL_COPY, 0);
return TRUE;
}
/* entry wasn't a single file, so let's iterate over section */
pFileEntries = SETUPX_GetSectionEntries(filename, pCopyEntry);
for (p=pFileEntries; *p; p +=strlen(p)+1)
{
@ -1126,30 +1129,34 @@ static BOOL SETUPX_CopyFiles(LPSTR *pSub, HINF16 hInf)
pSrcFile = *(pSubFile+1);
pDstFile = (*(DWORD *)pSubFile > 1) ? *(pSubFile+2) : pSrcFile;
TRACE("copying file '%s\\%s' to '%s\\%s'\n", pSrcDir, pSrcFile, pDstDir, pDstFile);
flag = 0;
if (*(DWORD *)pSubFile > 2)
{
WORD flag;
if ((flag = atoi(*(pSubFile+3)))) /* ah, flag */
{
if (flag & 0x2c)
FIXME("VNLP_xxx flag %d not handled yet.\n", flag);
}
else
FIXME("temp file name '%s' given. Need to register in wininit.ini !\n", *(pSubFile+3)); /* strong guess that this is VcpQueueCopy() */
{
FIXME("temp file name '%s' given. Need to register in wininit.ini !\n", *(pSubFile+3));
/* we probably need to set VIRTNODE.vhstrDstFinalName to
* the final destination name, and the temp name is merely
* the copy destination */
}
}
VcpQueueCopy16(pSrcFile, pDstFile, pSrcDir, pDstDir, LDID_SRCPATH, ldid ? ldid : 0xffff, 0, VFNL_COPY|flag, 0);
SETUPX_FreeSubStrings(pSubFile);
/* we don't copy ANYTHING yet ! (I'm too lazy and want to verify
* this first before destroying whole partitions ;-) */
}
}
return res;
return TRUE;
}
/***********************************************************************
* GenInstall
*
* general install function for .INF file sections
* generic installer function for .INF file sections
*
* This is not perfect - patch whenever you can !
*

709
dlls/setupapi/virtcopy.c Normal file
View File

@ -0,0 +1,709 @@
/*
* SetupAPI virtual copy operations
*
* FIXME: we now rely on builtin setupapi.dll for dialog resources.
* This is bad ! We ought to have 16bit resource handling working.
*/
#include <string.h>
#include "debugtools.h"
#include "windef.h"
#include "setupx16.h"
#include "heap.h"
#include "callback.h"
#include "stackframe.h"
#include "winreg.h"
#include "setupapi_private.h"
DEFAULT_DEBUG_CHANNEL(setupapi);
/* ### start build ### */
extern WORD CALLBACK VCP_CallTo16_word_lwwll(FARPROC16,LPVOID,UINT16,WPARAM,LPARAM,LPARAM);
/* ### stop build ### */
static FARPROC16 VCP_Proc = NULL;
static LPARAM VCP_MsgRef = 0;
#define VCP_CALLBACK(obj,msg,wParam,lParam,lParamRef) \
(VCP_Proc) ? \
VCP_CallTo16_word_lwwll(VCP_Proc, obj,msg,wParam,lParam,lParamRef) : OK;
static BOOL VCP_opened = FALSE;
static VCPSTATUS vcp_status;
static HINSTANCE SETUPAPI_hInstance;
/****************************** VHSTR management ******************************/
/*
* This is a totally braindead implementation for now;
* I don't care about speed at all ! Size and implementation time
* is much more important IMHO. I could have created some sophisticated
* tree structure, but... what the hell ! :-)
*/
typedef struct {
DWORD refcount;
LPCSTR pStr;
} VHSTR_STRUCT;
static VHSTR_STRUCT **vhstrlist = NULL;
static VHSTR vhstr_alloc = 0;
#define VALID_VHSTR(x) ((x < vhstr_alloc) && (vhstrlist[x]) && (vhstrlist[x]->refcount))
VHSTR WINAPI vsmStringAdd16(LPCSTR lpszName)
{
VHSTR n;
VHSTR index = 0xffff;
HANDLE heap;
TRACE("add string '%s'\n", lpszName);
/* search whether string already inserted */
for (n = 0; n < vhstr_alloc; n++)
{
if ((vhstrlist[n]) && (vhstrlist[n]->refcount))
{
TRACE("comp %d\n", n);
if (!strcmp(vhstrlist[n]->pStr, lpszName))
{
vhstrlist[n]->refcount++;
return n;
}
}
}
/* hmm, not found yet, let's insert it */
for (n = 0; n < vhstr_alloc; n++)
{
if ((!(vhstrlist[n])) || (!(vhstrlist[n]->refcount)))
{
index = n;
break;
}
}
heap = GetProcessHeap();
if (n == vhstr_alloc) /* hmm, no free index found yet */
{
index = vhstr_alloc;
vhstr_alloc += 20;
vhstrlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, vhstrlist,
sizeof(VHSTR_STRUCT *) * vhstr_alloc);
}
if (index == 0xffff)
return 0xffff; /* failure */
if (!vhstrlist[index])
vhstrlist[index] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VHSTR_STRUCT));
vhstrlist[index]->refcount = 1;
vhstrlist[index]->pStr = HeapAlloc(heap, 0, strlen(lpszName)+1);
strcpy((LPSTR)vhstrlist[index]->pStr, lpszName);
return index;
}
INT16 WINAPI vsmStringDelete16(VHSTR vhstr)
{
if (VALID_VHSTR(vhstr))
{
vhstrlist[vhstr]->refcount--;
if (!vhstrlist[vhstr]->refcount)
{
HeapFree(GetProcessHeap(), 0, (LPSTR)vhstrlist[vhstr]->pStr);
vhstrlist[vhstr]->pStr = NULL;
}
return VCPN_OK;
}
/* string not found */
return VCPN_FAIL;
}
/*
* vsmStringFind() - not exported from a standard SETUPX.DLL, it seems
*/
VHSTR WINAPI vsmStringFind16(LPCSTR lpszName)
{
WORD n;
for (n = 0; n < vhstr_alloc; n++)
if ((vhstrlist[n]) && (vhstrlist[n]->refcount) && (!strcmp(vhstrlist[n]->pStr, lpszName)))
return n;
return 0xffff;
}
/*
* vsmGetStringName()
*
* Pretty correct, I guess
*/
INT16 WINAPI vsmGetStringName16(VHSTR vhstr, LPSTR lpszBuffer, int cbBuffer)
{
if (VALID_VHSTR(vhstr))
{
int len = strlen(vhstrlist[vhstr]->pStr)+1;
if (cbBuffer >= len)
{
if (lpszBuffer)
strcpy(lpszBuffer, vhstrlist[vhstr]->pStr);
return len;
}
}
return VCPN_FAIL;
}
/*
* vsmStringCompare() - not exported from a standard SETUPX.DLL, it seems
*/
INT16 WINAPI vsmStringCompare16(VHSTR vhstrA, VHSTR vhstrB)
{
if ((!VALID_VHSTR(vhstrA)) || (!VALID_VHSTR(vhstrB)))
return VCPN_FAIL; /* correct ? */
return strcmp(vhstrlist[vhstrA]->pStr, vhstrlist[vhstrB]->pStr);
}
LPCSTR WINAPI vsmGetStringRawName16(VHSTR vhstr)
{
return (VALID_VHSTR(vhstr)) ? vhstrlist[vhstr]->pStr : NULL;
}
/***************************** VIRTNODE management ****************************/
static LPVIRTNODE *pvnlist = NULL;
static DWORD vn_num = 0;
static DWORD vn_last = 0;
RETERR16 VCP_VirtnodeCreate(LPVCPFILESPEC vfsSrc, LPVCPFILESPEC vfsDst, WORD fl, LPARAM lParam, LPEXPANDVTBL lpExpandVtbl)
{
HANDLE heap;
LPVIRTNODE lpvn;
RETERR16 cbres;
while (vn_last < vn_num)
{
if (pvnlist[vn_last] == NULL)
break;
vn_last++;
}
heap = GetProcessHeap();
if (vn_last == vn_num)
{
vn_num += 20;
pvnlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, pvnlist,
sizeof(LPVIRTNODE *) * vn_num);
}
pvnlist[vn_last] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VIRTNODE));
lpvn = pvnlist[vn_last];
vn_last++;
lpvn->cbSize = sizeof(VIRTNODE);
if (vfsSrc)
memcpy(&lpvn->vfsSrc, vfsSrc, sizeof(VCPFILESPEC));
if (vfsDst)
memcpy(&lpvn->vfsDst, vfsDst, sizeof(VCPFILESPEC));
lpvn->fl = fl;
lpvn->lParam = lParam;
lpvn->lpExpandVtbl = lpExpandVtbl;
lpvn->vhstrDstFinalName = 0xffff; /* FIXME: what is this ? */
cbres = VCP_CALLBACK(lpvn, VCPM_NODECREATE, 0, 0, VCP_MsgRef);
lpvn->fl |= VFNL_CREATED;
cbres = VCP_CALLBACK(lpvn, VCPM_NODEACCEPT, 0, 0, VCP_MsgRef);
return OK;
}
BOOL VCP_VirtnodeDelete(LPVIRTNODE lpvnDel)
{
DWORD n;
RETERR16 cbres;
for (n = 0; n < vn_last; n++)
{
if (pvnlist[n] == lpvnDel)
{
cbres = VCP_CALLBACK(lpvnDel, VCPM_NODEDESTROY, 0, 0, VCP_MsgRef);
HeapFree(GetProcessHeap(), 0, lpvnDel);
pvnlist[n] = NULL;
return TRUE;
}
}
return FALSE;
}
/***********************************************************************
* VcpOpen
*
* Sets up a virtual copy operation.
* This means that functions such as GenInstall()
* create a VIRTNODE struct for every file to be touched in a .INF file
* instead of actually touching the file.
* The actual copy/move/rename gets started when VcpClose or
* VcpFlush is called; several different callbacks are made
* (copy, rename, open, close, version conflicts, ...) on every file copied.
*/
RETERR16 WINAPI VcpOpen16(VIFPROC vifproc, LPARAM lparamMsgRef)
{
TRACE("(%p, %08lx)\n", vifproc, lparamMsgRef);
if (VCP_opened)
return ERR_VCP_BUSY;
VCP_Proc = (FARPROC16)vifproc;
VCP_MsgRef = lparamMsgRef;
/* load SETUPAPI needed for dialog resources etc. */
SETUPAPI_hInstance = LoadLibraryA("setupapi.dll");
if (!SETUPAPI_hInstance)
{
ERR("Could not load sibling setupapi.dll\n");
return ERR_VCP_NOMEM;
}
VCP_opened = TRUE;
return OK;
}
/***********************************************************************
* VcpQueueCopy [SETUPX.13]
*
* lpExpandVtbl seems to be deprecated.
* fl are the CNFL_xxx and VNFL_xxx flags.
* lParam are the VNLP_xxx flags.
*/
RETERR16 WINAPI VcpQueueCopy16(
LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
LPEXPANDVTBL lpExpandVtbl,
WORD fl, LPARAM lParam
)
{
VCPFILESPEC vfsSrc, vfsDst;
if (!VCP_opened)
return ERR_VCP_NOTOPEN;
vfsSrc.ldid = ldidSrc;
vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);
vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);
vfsDst.ldid = ldidDst;
vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, fl, lParam,
lpExpandVtbl);
}
/***********************************************************************
* VcpQueueDelete [SETUPX.17]
*
* Is lParamRef the same as lParam in VcpQueueCopy ?
* Damn docu !! Err... which docu ?
*/
RETERR16 WINAPI VcpQueueDelete16(
LPCSTR lpszDstFileName,
LPCSTR lpszDstDir,
LOGDISKID16 ldidDst,
LPEXPANDVTBL lpExpandVtbl,
LPARAM lParamRef
)
{
VCPFILESPEC vfsDst;
if (!VCP_opened)
return ERR_VCP_NOTOPEN;
vfsDst.ldid = ldidDst;
vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
return VCP_VirtnodeCreate(NULL, &vfsDst, VNFL_DELETE, lParamRef,
lpExpandVtbl);
}
/***********************************************************************
* VcpQueueRename [SETUPX.204]
*
*/
RETERR16 WINAPI VcpQueueRename16(
LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
LPARAM lParam
)
{
VCPFILESPEC vfsSrc, vfsDst;
if (!VCP_opened)
return ERR_VCP_NOTOPEN;
vfsSrc.ldid = ldidSrc;
vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);
vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);
vfsDst.ldid = ldidDst;
vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, VNFL_RENAME, lParam,
0);
}
INT16 WINAPI VcpEnumFiles(VCPENUMPROC vep, LPARAM lParamRef)
{
WORD n;
for (n = 0; n < vn_last; n++)
vep(pvnlist[n], lParamRef);
return 0; /* FIXME: return value ? */
}
LPCSTR WINAPI VcpExplain16(LPVIRTNODE lpVn, DWORD dwWhat)
{
static char buffer[MAX_PATH]; /* FIXME: is this how it's done ? */
buffer[0] = '\0';
switch (dwWhat)
{
case VCPEX_SRC_FULL:
case VCPEX_DST_FULL:
{
LPVCPFILESPEC lpvfs =
(dwWhat == VCPEX_SRC_FULL) ? &lpVn->vfsSrc : &lpVn->vfsDst;
if (lpvfs->ldid != 0xffff)
CtlGetLddPath16(lpvfs->ldid, buffer);
strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrDir));
strcat(buffer, "\\");
strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrFileName));
}
break;
default:
FIXME("%ld unimplemented !\n", dwWhat);
strcpy(buffer, "Unknown error");
break;
}
return buffer;
}
RETERR16 VCP_CheckPaths(void)
{
DWORD n;
LPVIRTNODE lpvn;
RETERR16 cbres;
cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATPATHCHECKSTART, 0, 0, VCP_MsgRef);
for (n = 0; n < vn_num; n++)
{
lpvn = pvnlist[n];
if (!lpvn) continue;
/* FIXME: check paths of all VIRTNODEs here ! */
cbres = VCP_CALLBACK(&lpvn->vfsDst, VCPM_CHECKPATH, 0, (DWORD)lpvn, VCP_MsgRef);
}
cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATPATHCHECKEND, 0, 0, VCP_MsgRef);
return OK;
}
RETERR16 VCP_CopyFiles(void)
{
char fn_src[MAX_PATH], fn_dst[MAX_PATH];
RETERR16 res = OK, cbres;
DWORD n;
LPVIRTNODE lpvn;
cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATCOPYSTART, 0, 0, VCP_MsgRef);
for (n = 0; n < vn_num; n++)
{
lpvn = pvnlist[n];
if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_COPY)) continue;
/* FIXME: need to send VCPM_VSTATNEWDISK notification sometimes */
strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));
strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));
/* FIXME: what is this VCPM_VSTATWRITE here for ?
* I guess it's to signal successful destination file creation */
cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);
/* FIXME: need to do the file copy in small chunks for notifications */
TRACE("copying '%s' to '%s'\n", fn_src, fn_dst);
#if DO_A_REAL_COPY
if (!(CopyFileA(fn_src, fn_dst, TRUE)))
res = ERR_VCP_IOFAIL;
#endif
vcp_status.prgFileRead.dwSoFar++;
cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATREAD, 0, 0, VCP_MsgRef);
vcp_status.prgFileWrite.dwSoFar++;
cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);
}
cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATCOPYEND, 0, 0, VCP_MsgRef);
return res;
}
/***********************************************************************
* VcpFlush - internal (not exported), but documented
*
* VNFL_NOW is used for VcpFlush.
*/
RETERR16 VcpFlush16(WORD fl, LPCSTR lpszBackupDest)
{
return OK;
}
/***********************************************************************
* VcpClose
*
* Does callbacks (-> vifproc) with VCPM_VSTATCLOSESTART,
* VCPM_VSTATCLOSEEND.
*
* fl gets VCPFL_xxx flags to indicate what to do with the
* VIRTNODEs (files to mess with) created by e.g. GenInstall()
*/
RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest)
{
RETERR16 res = OK;
WORD cbres = VCPN_PROCEED;
TRACE("(%04x, '%s')\n", fl, lpszBackupDest);
/* FIXME: needs to sort virtnodes in case VCPFL_INSPECIFIEDORDER
* is not set. This is done by VCP_CALLBACK(VCPM_NODECOMPARE) */
TRACE("#1\n");
memset(&vcp_status, 0, sizeof(VCPSTATUS));
/* yes, vcp_status.cbSize is 0 ! */
TRACE("#2\n");
cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATCLOSESTART, 0, 0, VCP_MsgRef);
TRACE("#3\n");
res = VCP_CheckPaths();
TRACE("#4\n");
if (res != OK)
return res; /* is this ok ? */
VCP_CopyFiles();
TRACE("#5\n");
cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATCLOSEEND, 0, 0, VCP_MsgRef);
TRACE("#6\n");
VCP_Proc = NULL;
FreeLibrary(SETUPAPI_hInstance);
VCP_opened = FALSE;
return OK;
}
RETERR16 VCP_RenameFiles(void)
{
char fn_src[MAX_PATH], fn_dst[MAX_PATH];
RETERR16 res = OK, cbres;
DWORD n;
LPVIRTNODE lpvn;
cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATRENAMESTART, 0, 0, VCP_MsgRef);
for (n = 0; n < vn_num; n++)
{
lpvn = pvnlist[n];
if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_RENAME)) continue;
strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));
strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));
cbres = VCP_CALLBACK(&lpvn->vfsDst, VCPM_FILEOPENOUT, 0, (LPARAM)lpvn, VCP_MsgRef);
if (!(MoveFileExA(fn_src, fn_dst, MOVEFILE_REPLACE_EXISTING)))
res = ERR_VCP_IOFAIL;
else
VCP_VirtnodeDelete(lpvn);
}
cbres = VCP_CALLBACK(&vcp_status, VCPM_VSTATRENAMEEND, 0, 0, VCP_MsgRef);
return res;
}
RETERR16 WINAPI vcpDefCallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
LPARAM lParam, LPARAM lParamRef)
{
static int count = 0;
if (count < 10)
FIXME("(%p, %04x, %04x, %08lx, %08lx) - what to do here ?\n",
lpvObj, uMsg, wParam, lParam, lParamRef);
count++;
return OK;
}
/********************* point-and-click stuff from here ***********************/
static HWND hDlgCopy = 0;
static HKEY hKeyFiles = 0, hKeyRename = 0, hKeyConflict = 0;
static char BackupDir[12];
static BOOL CALLBACK VCP_UI_FileCopyDlgProc(HWND hWndDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
BOOL retval = FALSE;
if (iMsg == WM_INITDIALOG)
{
ShowWindow(hWndDlg, SW_SHOWNORMAL);
UpdateWindow(hWndDlg);
retval = TRUE;
}
return retval;
}
BOOL VCP_UI_GetDialogTemplate(LPCVOID *template32)
{
HANDLE hResInfo, hDlgTmpl32;
if (!(hResInfo = FindResourceA(SETUPAPI_hInstance, MAKEINTRESOURCEA(COPYFILEDLGORD), RT_DIALOGA)))
return FALSE;
if (!(hDlgTmpl32 = LoadResource(SETUPAPI_hInstance, hResInfo )) ||
!(*template32 = LockResource( hDlgTmpl32 )))
return FALSE;
return TRUE;
}
static LRESULT WINAPI
VCP_UI_FileCopyWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg != WM_CREATE)
return DefWindowProcA (hwnd, uMsg, wParam, lParam);
switch (uMsg)
{
case WM_CREATE:
return 0;
default:
FIXME("%04x: unhandled.\n", uMsg);
}
return 0;
}
void VCP_UI_RegisterProgressClass(void)
{
static BOOL registered = FALSE;
WNDCLASSA wndClass;
if (registered)
return;
registered = TRUE;
ZeroMemory (&wndClass, sizeof(WNDCLASSA));
wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = (WNDPROC)VCP_UI_FileCopyWndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
wndClass.hbrBackground = (HBRUSH)NULL;
wndClass.lpszClassName = "setupx_progress";
RegisterClassA (&wndClass);
}
RETERR16 VCP_UI_NodeCompare(LPVIRTNODE vn1, LPVIRTNODE vn2)
{
LPCSTR file1, file2;
file1 = vsmGetStringRawName16(vn1->vfsSrc.vhstrFileName);
file2 = vsmGetStringRawName16(vn2->vfsSrc.vhstrFileName);
return (RETERR16)strcmp(file1, file2);
}
RETERR16 VCP_UI_CopyStart(void)
{
LPCVOID template32;
char buf[256]; /* plenty */
BOOL dirty;
DWORD len;
/* FIXME: should be registered at DLL startup instead */
VCP_UI_RegisterProgressClass();
if (!(VCP_UI_GetDialogTemplate(&template32)))
return VCPN_FAIL;
hDlgCopy = CreateDialogIndirectParamA(SETUPAPI_hInstance, template32, 0,
VCP_UI_FileCopyDlgProc, 0);
if (!hDlgCopy)
return VCPN_FAIL;
SetDlgItemTextA(hDlgCopy, SOURCESTRORD, "Scanning ...");
SetDlgItemTextA(hDlgCopy, DESTSTRORD, "NOT_IMPLEMENTED_YET");
strcpy(buf, REG_INSTALLEDFILES);
if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyFiles))
return VCPN_FAIL;
strcat(buf, REGPART_RENAME);
if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyRename))
return VCPN_FAIL;
if (RegCreateKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT, &hKeyConflict))
return VCPN_FAIL;
len = 1;
if (!(RegQueryValueExA(hKeyConflict, "Dirty", NULL, 0, (LPBYTE)&dirty, &len)))
{
/* FIXME: what does SETUPX.DLL do in this case ? */
MESSAGE("Warning: another program using SETUPX is already running ! Failed.\n");
return VCPN_FAIL;
}
dirty = TRUE;
if (RegSetValueExA(hKeyConflict, "Dirty", 0, REG_BINARY, (LPBYTE)&dirty, 1))
return VCPN_FAIL;
len = 12;
if (!(RegQueryValueExA(hKeyConflict, "BackupDirectory", NULL, 0, BackupDir, &len)))
strcpy(BackupDir, "VCM");
/* create C:\WINDOWS\[BackupDir] and set registry key to it */
GetWindowsDirectoryA(buf, 256);
strcat(buf, "\\");
strcat(buf, BackupDir);
if (!(CreateDirectoryA(buf, NULL)))
return VCPN_FAIL;
if (RegSetValueExA(hKeyConflict, "BackupDirectory", 0, REG_SZ, (LPBYTE)buf, strlen(buf)+1))
return VCPN_FAIL;
RegCloseKey(hKeyConflict);
return VCPN_OK;
}
RETERR16 WINAPI vcpUICallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
LPARAM lParam, LPARAM lParamRef)
{
static int count = 0;
RETERR16 res = VCPN_OK, cbres;
if (count < 5)
FIXME("(%p, %04x, %04x, %08lx, %08lx) - semi-stub\n",
lpvObj, uMsg, wParam, lParam, lParamRef);
count++;
switch (uMsg)
{
/* unused messages, it seems */
case VCPM_DISKPREPINFO:
case VCPM_FILENEEDED:
case VCPM_NODECREATE:
case VCPM_NODEACCEPT:
case VCPM_VSTATCLOSESTART:
case VCPM_VSTATPATHCHECKSTART:
case VCPM_VSTATPATHCHECKEND:
case VCPM_CHECKPATH:
break;
/* the real stuff */
case VCPM_NODECOMPARE:
res = VCP_UI_NodeCompare((LPVIRTNODE)lpvObj, (LPVIRTNODE)lParam);
break;
case VCPM_VSTATREAD:
break;
case VCPM_VSTATWRITE:
cbres = VCP_CALLBACK(&vcp_status, VCPM_DISKPREPINFO, 0, 0, VCP_MsgRef);
break;
case VCPM_VSTATCLOSEEND:
RegCloseKey(hKeyFiles);
RegCloseKey(hKeyRename);
RegDeleteKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT);
break;
case VCPM_VSTATCOPYSTART:
res = VCP_UI_CopyStart();
break;
case VCPM_VSTATCOPYEND:
DestroyWindow(hDlgCopy);
break;
default:
FIXME("unhandled msg 0x%04x\n", uMsg);
}
return res;
}