- 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
|
||||
setupapi.res
|
||||
setupapi.spec.c
|
||||
setupx.spec.c
|
||||
virtcopy.glue.c
|
||||
|
|
|
@ -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@
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
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
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 !
|
||||
*
|
||||
|
|
|
@ -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