- 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:
parent
793bf04e24
commit
9bebbc5d8e
|
@ -1,3 +1,5 @@
|
||||||
Makefile
|
Makefile
|
||||||
|
setupapi.res
|
||||||
setupapi.spec.c
|
setupapi.spec.c
|
||||||
setupx.spec.c
|
setupx.spec.c
|
||||||
|
virtcopy.glue.c
|
||||||
|
|
|
@ -13,7 +13,14 @@ C_SRCS = \
|
||||||
devinst.c \
|
devinst.c \
|
||||||
infparse.c \
|
infparse.c \
|
||||||
setupx_main.c \
|
setupx_main.c \
|
||||||
stubs.c
|
stubs.c \
|
||||||
|
virtcopy.c
|
||||||
|
|
||||||
|
GLUE = \
|
||||||
|
virtcopy.c
|
||||||
|
|
||||||
|
RC_SRCS= \
|
||||||
|
setupapi.rc
|
||||||
|
|
||||||
@MAKE_DLL_RULES@
|
@MAKE_DLL_RULES@
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
#include "setupx16.h"
|
#include "setupx16.h"
|
||||||
#include "setupx_private.h"
|
#include "setupapi_private.h"
|
||||||
|
|
||||||
DEFAULT_DEBUG_CHANNEL(setupx);
|
DEFAULT_DEBUG_CHANNEL(setupapi);
|
||||||
|
|
||||||
WORD InfNumEntries = 0;
|
WORD InfNumEntries = 0;
|
||||||
INF_FILE *InfList = NULL;
|
INF_FILE *InfList = NULL;
|
||||||
|
|
|
@ -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
|
|
@ -1,11 +1,13 @@
|
||||||
name setupapi
|
name setupapi
|
||||||
type win32
|
type win32
|
||||||
|
rsrc setupapi.res
|
||||||
|
|
||||||
|
import user32.dll
|
||||||
import advapi32.dll
|
import advapi32.dll
|
||||||
import kernel32.dll
|
import kernel32.dll
|
||||||
import ntdll.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
|
# almost all functions are commented out for now. Ordinals are from setupapi.dll 4.0
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
#ifndef __SETUPX_PRIVATE_H
|
#ifndef __SETUPAPI_PRIVATE_H
|
||||||
#define __SETUPX_PRIVATE_H
|
#define __SETUPAPI_PRIVATE_H
|
||||||
|
|
||||||
#include "wine/windef16.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 {
|
typedef struct tagLDD_LIST {
|
||||||
LPLOGDISKDESC pldd;
|
LPLOGDISKDESC pldd;
|
||||||
struct tagLDD_LIST *next;
|
struct tagLDD_LIST *next;
|
||||||
|
@ -26,4 +36,4 @@ extern WORD InfNumEntries;
|
||||||
|
|
||||||
extern LPCSTR IP_GetFileName(HINF16 hInf);
|
extern LPCSTR IP_GetFileName(HINF16 hInf);
|
||||||
|
|
||||||
#endif /* __SETUPX_PRIVATE_H */
|
#endif /* __SETUPAPI_PRIVATE_H */
|
|
@ -14,11 +14,11 @@ owner setupapi
|
||||||
10 stub IpGetIntField #(word ptr word ptr)
|
10 stub IpGetIntField #(word ptr word ptr)
|
||||||
11 stub IpFindNextLine #(word ptr)
|
11 stub IpFindNextLine #(word ptr)
|
||||||
12 stub IpGetFileName #(word ptr word)
|
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
|
14 stub NOAUTORUNWNDPROC
|
||||||
15 stub __DEBUGMSG
|
15 stub __DEBUGMSG
|
||||||
16 stub __ASSERTMSG
|
16 stub __ASSERTMSG
|
||||||
17 stub VcpQueueDelete #(str str word long)
|
17 pascal16 VcpQueueDelete(str str word long) VcpQueueDelete16
|
||||||
18 stub TpOpenFile #(str ptr word)
|
18 stub TpOpenFile #(str ptr word)
|
||||||
19 stub TpCloseFile #(word)
|
19 stub TpCloseFile #(word)
|
||||||
20 stub TpOpenSection #(word ptr str word)
|
20 stub TpOpenSection #(word ptr str word)
|
||||||
|
@ -62,6 +62,7 @@ owner setupapi
|
||||||
61 stub suErrorToIds #(word word)
|
61 stub suErrorToIds #(word word)
|
||||||
62 stub TPWriteProfileString #(str str str)
|
62 stub TPWriteProfileString #(str str str)
|
||||||
63 stub SURPLSETUP
|
63 stub SURPLSETUP
|
||||||
|
# does SUSTORELDIDPATH set the path of an LDID in the registry ?
|
||||||
64 stub SUSTORELDIDPATH
|
64 stub SUSTORELDIDPATH
|
||||||
65 stub WILDCARDSTRCMPI
|
65 stub WILDCARDSTRCMPI
|
||||||
101 pascal16 GenInstall(word str word) GenInstall16
|
101 pascal16 GenInstall(word str word) GenInstall16
|
||||||
|
@ -122,20 +123,20 @@ owner setupapi
|
||||||
160 stub SXUPDATEDS
|
160 stub SXUPDATEDS
|
||||||
170 stub SUSETMEM
|
170 stub SUSETMEM
|
||||||
171 stub WriteDMFBootData #(word ptr word)
|
171 stub WriteDMFBootData #(word ptr word)
|
||||||
200 pascal VcpOpen(ptr str) VcpOpen16
|
200 pascal VcpOpen(segptr ptr) VcpOpen16
|
||||||
201 pascal VcpClose(word str) VcpClose16
|
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)
|
203 stub vcpEnumFiles #(ptr long)
|
||||||
204 stub VcpQueueRename #(str str str str word word long)
|
204 pascal16 VcpQueueRename(str str str str word word long) VcpQueueRename16
|
||||||
205 stub vsmGetStringName #(word ptr word)
|
205 pascal16 vsmGetStringName(word ptr word) vsmGetStringName16
|
||||||
206 stub vsmStringDelete #(word)
|
206 pascal16 vsmStringDelete(word) vsmStringDelete16
|
||||||
207 stub vsmStringAdd #(str)
|
207 pascal16 vsmStringAdd(str) vsmStringAdd16
|
||||||
208 stub vsmGetStringRawName #(word)
|
208 pascal vsmGetStringRawName(word) vsmGetStringRawName16
|
||||||
209 stub IpSaveRestorePosition #(word word)
|
209 stub IpSaveRestorePosition #(word word)
|
||||||
210 pascal16 IpGetProfileString(word str str ptr word) IpGetProfileString16
|
210 pascal16 IpGetProfileString(word str str ptr word) IpGetProfileString16
|
||||||
211 stub IpOpenEx #(str ptr word)
|
211 stub IpOpenEx #(str ptr word)
|
||||||
212 stub IpOpenAppendEx #(str word 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)
|
214 stub VcpAddMRUPath #(str)
|
||||||
300 stub DiBuildCompatDrvList #(ptr)
|
300 stub DiBuildCompatDrvList #(ptr)
|
||||||
301 stub DiBuildClassDrvList #(ptr)
|
301 stub DiBuildClassDrvList #(ptr)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
typedef UINT16 HINF16;
|
typedef UINT16 HINF16;
|
||||||
typedef UINT16 LOGDISKID16;
|
typedef UINT16 LOGDISKID16;
|
||||||
|
typedef UINT16 VHSTR;
|
||||||
|
|
||||||
#define LINE_LEN 256
|
#define LINE_LEN 256
|
||||||
|
|
||||||
|
@ -18,7 +19,7 @@ typedef UINT16 RETERR16;
|
||||||
#define GEN_ERROR (UINT16)400
|
#define GEN_ERROR (UINT16)400
|
||||||
#define DI_ERROR (UINT16)500
|
#define DI_ERROR (UINT16)500
|
||||||
|
|
||||||
enum _IP_ERR {
|
enum {
|
||||||
ERR_IP_INVALID_FILENAME = IP_ERROR+1,
|
ERR_IP_INVALID_FILENAME = IP_ERROR+1,
|
||||||
ERR_IP_ALLOC_ERR,
|
ERR_IP_ALLOC_ERR,
|
||||||
ERR_IP_INVALID_SECT_NAME,
|
ERR_IP_INVALID_SECT_NAME,
|
||||||
|
@ -37,7 +38,113 @@ enum _IP_ERR {
|
||||||
ERR_IP_INVALID_INFTYPE
|
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_IOFAIL = VCP_ERROR+1,
|
||||||
ERR_VCP_STRINGTOOLONG,
|
ERR_VCP_STRINGTOOLONG,
|
||||||
ERR_VCP_NOMEM,
|
ERR_VCP_NOMEM,
|
||||||
|
@ -65,6 +172,205 @@ enum _ERR_VCP {
|
||||||
ERR_VCP_NO_DIGITAL_SIGNATURE_FILE
|
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 ******/
|
/****** logical disk management ******/
|
||||||
|
|
||||||
typedef struct _LOGDISKDESC_S { /* ldd */
|
typedef struct _LOGDISKDESC_S { /* ldd */
|
||||||
|
@ -198,8 +504,6 @@ typedef struct _DEVICE_INFO
|
||||||
} DEVICE_INFO16, *LPDEVICE_INFO16, **LPLPDEVICE_INFO16;
|
} 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 void WINAPI GenFormStrWithoutPlaceHolders16(LPSTR,LPCSTR,HINF16);
|
||||||
extern RETERR16 WINAPI IpOpen16(LPCSTR,HINF16 *);
|
extern RETERR16 WINAPI IpOpen16(LPCSTR,HINF16 *);
|
||||||
extern RETERR16 WINAPI IpClose16(HINF16);
|
extern RETERR16 WINAPI IpClose16(HINF16);
|
||||||
|
@ -208,6 +512,7 @@ extern RETERR16 WINAPI CtlGetLdd16(LPLOGDISKDESC);
|
||||||
extern RETERR16 WINAPI CtlFindLdd16(LPLOGDISKDESC);
|
extern RETERR16 WINAPI CtlFindLdd16(LPLOGDISKDESC);
|
||||||
extern RETERR16 WINAPI CtlAddLdd16(LPLOGDISKDESC);
|
extern RETERR16 WINAPI CtlAddLdd16(LPLOGDISKDESC);
|
||||||
extern RETERR16 WINAPI CtlDelLdd16(LOGDISKID16);
|
extern RETERR16 WINAPI CtlDelLdd16(LOGDISKID16);
|
||||||
|
extern RETERR16 WINAPI CtlGetLddPath16(LOGDISKID16 ldid, LPSTR szPath);
|
||||||
extern RETERR16 WINAPI GenInstall16(HINF16,LPCSTR,WORD);
|
extern RETERR16 WINAPI GenInstall16(HINF16,LPCSTR,WORD);
|
||||||
|
|
||||||
#endif /* __SETUPX16_H */
|
#endif /* __SETUPX16_H */
|
||||||
|
|
|
@ -47,12 +47,12 @@
|
||||||
#include "winreg.h"
|
#include "winreg.h"
|
||||||
#include "wine/winuser16.h"
|
#include "wine/winuser16.h"
|
||||||
#include "setupx16.h"
|
#include "setupx16.h"
|
||||||
#include "setupx_private.h"
|
#include "setupapi_private.h"
|
||||||
#include "winerror.h"
|
#include "winerror.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
|
|
||||||
DEFAULT_DEBUG_CHANNEL(setupx);
|
DEFAULT_DEBUG_CHANNEL(setupapi);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* SURegOpenKey
|
* SURegOpenKey
|
||||||
|
@ -292,7 +292,7 @@ RETERR16 WINAPI InstallHinfSection16( HWND16 hwnd, HINSTANCE16 hinst, LPCSTR lps
|
||||||
LPSTR *pSub;
|
LPSTR *pSub;
|
||||||
DWORD count;
|
DWORD count;
|
||||||
HINF16 hInf = 0;
|
HINF16 hInf = 0;
|
||||||
RETERR16 res = OK;
|
RETERR16 res = OK, tmp;
|
||||||
WORD wFlags;
|
WORD wFlags;
|
||||||
BOOL reboot = FALSE;
|
BOOL reboot = FALSE;
|
||||||
HMODULE hMod;
|
HMODULE hMod;
|
||||||
|
@ -310,6 +310,8 @@ RETERR16 WINAPI InstallHinfSection16( HWND16 hwnd, HINSTANCE16 hinst, LPCSTR lps
|
||||||
res = ERROR_FILE_NOT_FOUND; /* yes, correct */
|
res = ERROR_FILE_NOT_FOUND; /* yes, correct */
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
if (VcpOpen16(NULL, 0))
|
||||||
|
goto end;
|
||||||
if (GenInstall16(hInf, *(pSub+count-2), GENINSTALL_DO_ALL) != OK)
|
if (GenInstall16(hInf, *(pSub+count-2), GENINSTALL_DO_ALL) != OK)
|
||||||
goto end;
|
goto end;
|
||||||
wFlags = atoi(*(pSub+count-1)) & ~128;
|
wFlags = atoi(*(pSub+count-1)) & ~128;
|
||||||
|
@ -338,7 +340,12 @@ RETERR16 WINAPI InstallHinfSection16( HWND16 hwnd, HINSTANCE16 hinst, LPCSTR lps
|
||||||
|
|
||||||
res = OK;
|
res = OK;
|
||||||
end:
|
end:
|
||||||
IpClose16(hInf);
|
tmp = VcpClose16(VCPFL_ALL, NULL);
|
||||||
|
if (tmp != OK)
|
||||||
|
res = tmp;
|
||||||
|
tmp = IpClose16(hInf);
|
||||||
|
if (tmp != OK)
|
||||||
|
res = tmp;
|
||||||
SETUPX_FreeSubStrings(pSub);
|
SETUPX_FreeSubStrings(pSub);
|
||||||
if (reboot)
|
if (reboot)
|
||||||
{
|
{
|
||||||
|
@ -502,7 +509,7 @@ static const LDID_DATA LDID_Data[34] =
|
||||||
* LDID == Logical Device ID
|
* LDID == Logical Device ID
|
||||||
*
|
*
|
||||||
* The whole LDD/LDID business might go into a separate file named
|
* 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.
|
* At the moment I don't know what the hell these functions are really doing.
|
||||||
* That's why I added reporting stubs.
|
* That's why I added reporting stubs.
|
||||||
* The only thing I do know is that I need them for the LDD/LDID infrastructure.
|
* 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);
|
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
|
* 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)
|
static BOOL SETUPX_CopyFiles(LPSTR *pSub, HINF16 hInf)
|
||||||
{
|
{
|
||||||
BOOL res = FALSE;
|
BOOL bSingle = FALSE;
|
||||||
unsigned int n;
|
unsigned int n;
|
||||||
LPCSTR filename = IP_GetFileName(hInf);
|
LPCSTR filename = IP_GetFileName(hInf);
|
||||||
LPSTR pCopyEntry;
|
LPSTR pCopyEntry;
|
||||||
char pDestStr[MAX_PATH];
|
char pDstStr[MAX_PATH];
|
||||||
LPSTR pSrcDir, pDstDir;
|
LPSTR pSrcDir, pDstDir;
|
||||||
LPSTR pFileEntries, p;
|
LPSTR pFileEntries, p;
|
||||||
WORD ldid;
|
WORD ldid;
|
||||||
LOGDISKDESC_S ldd;
|
LOGDISKDESC_S ldd;
|
||||||
LPSTR *pSubFile;
|
LPSTR *pSubFile;
|
||||||
LPSTR pSrcFile, pDstFile;
|
LPSTR pSrcFile, pDstFile;
|
||||||
|
WORD flag;
|
||||||
|
|
||||||
for (n=0; n < *(DWORD *)pSub; n++)
|
for (n=0; n < *(DWORD *)pSub; n++)
|
||||||
{
|
{
|
||||||
pCopyEntry = *(pSub+1+n);
|
pCopyEntry = *(pSub+1+n);
|
||||||
if (*pCopyEntry == '@')
|
if (*pCopyEntry == '@')
|
||||||
{
|
{
|
||||||
ERR("single file not handled yet !\n");
|
pCopyEntry++;
|
||||||
continue;
|
bSingle = TRUE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
bSingle = FALSE;
|
||||||
|
|
||||||
/* get source directory for that entry */
|
/* get source directory for that entry */
|
||||||
INIT_LDD(ldd, LDID_SRCPATH);
|
INIT_LDD(ldd, LDID_SRCPATH);
|
||||||
|
@ -1105,20 +1093,35 @@ static BOOL SETUPX_CopyFiles(LPSTR *pSub, HINF16 hInf)
|
||||||
|
|
||||||
/* get destination directory for that entry */
|
/* get destination directory for that entry */
|
||||||
if (!(GetPrivateProfileStringA("DestinationDirs", pCopyEntry, "",
|
if (!(GetPrivateProfileStringA("DestinationDirs", pCopyEntry, "",
|
||||||
pDestStr, sizeof(pDestStr), filename)))
|
pDstStr, sizeof(pDstStr), filename)))
|
||||||
continue;
|
{
|
||||||
|
/* 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 */
|
/* translate destination dir if given as LDID */
|
||||||
ldid = atoi(pDestStr);
|
ldid = atoi(pDstStr);
|
||||||
if (ldid)
|
if (ldid)
|
||||||
{
|
{
|
||||||
if (!(SETUPX_IP_TranslateLDID(ldid, &pDstDir, hInf)))
|
if (!(SETUPX_IP_TranslateLDID(ldid, &pDstDir, hInf)))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
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);
|
pFileEntries = SETUPX_GetSectionEntries(filename, pCopyEntry);
|
||||||
for (p=pFileEntries; *p; p +=strlen(p)+1)
|
for (p=pFileEntries; *p; p +=strlen(p)+1)
|
||||||
{
|
{
|
||||||
|
@ -1126,30 +1129,34 @@ static BOOL SETUPX_CopyFiles(LPSTR *pSub, HINF16 hInf)
|
||||||
pSrcFile = *(pSubFile+1);
|
pSrcFile = *(pSubFile+1);
|
||||||
pDstFile = (*(DWORD *)pSubFile > 1) ? *(pSubFile+2) : pSrcFile;
|
pDstFile = (*(DWORD *)pSubFile > 1) ? *(pSubFile+2) : pSrcFile;
|
||||||
TRACE("copying file '%s\\%s' to '%s\\%s'\n", pSrcDir, pSrcFile, pDstDir, pDstFile);
|
TRACE("copying file '%s\\%s' to '%s\\%s'\n", pSrcDir, pSrcFile, pDstDir, pDstFile);
|
||||||
|
flag = 0;
|
||||||
if (*(DWORD *)pSubFile > 2)
|
if (*(DWORD *)pSubFile > 2)
|
||||||
{
|
{
|
||||||
WORD flag;
|
|
||||||
if ((flag = atoi(*(pSubFile+3)))) /* ah, flag */
|
if ((flag = atoi(*(pSubFile+3)))) /* ah, flag */
|
||||||
{
|
{
|
||||||
if (flag & 0x2c)
|
if (flag & 0x2c)
|
||||||
FIXME("VNLP_xxx flag %d not handled yet.\n", flag);
|
FIXME("VNLP_xxx flag %d not handled yet.\n", flag);
|
||||||
}
|
}
|
||||||
else
|
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);
|
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
|
* GenInstall
|
||||||
*
|
*
|
||||||
* general install function for .INF file sections
|
* generic installer function for .INF file sections
|
||||||
*
|
*
|
||||||
* This is not perfect - patch whenever you can !
|
* This is not perfect - patch whenever you can !
|
||||||
*
|
*
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue