- implement some more virtcopy (VCP) stuff

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

View File

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

View File

@ -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@

View File

@ -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;

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

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

View File

@ -1,11 +1,13 @@
name setupapi 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

View File

@ -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 */

View File

@ -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)

View File

@ -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 */

View File

@ -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 !
* *

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

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