I'm having a problem with a System::Call to an external DLL.
What I want to do is to port an existing InstallShield installer
for a driver to NSIS.
I've read the Readme, studied several examples but can't found what's wrong.
In a custom action of IS a SetupAPI calls are performed to copy/uninstall
an OEM inffile.
SetupCopyOEMInf/SetupUninstallOEMInf are declared as follows:
BOOL WINAPI SetupCopyOEMInf(
PCTSTR SourceInfFileName,
PCTSTR OEMSourceMediaLocation,
DWORD OEMSourceMediaType,
DWORD CopyStyle,
PTSTR DestinationInfFileName,
DWORD DestinationInfFileNameSize,
PDWORD RequiredSize,
PTSTR DestinationInfFileNameComponent
);
BOOL SetupUninstallOEMInf(
PCWSTR InfFileName,
DWORD Flags,
PVOID Reserved
);
I translated these into:
!define SETUP_COPY_OEM_INFA "SetupAPI::SetupCopyOEMInfA (t, t, i, i, *t, i, i, *t) i"
!define SETUP_UNINSTALL_OEM_INFA "SetupAPI::SetupUninstallOEMInfA (t, i, *i) i"
with the calls being:
System::Call '${SETUP_COPY_OEM_INFA} (r0,,0, 2, .r2, ${NSIS_MAX_STRLEN},, )'
System::Call "${SETUP_UNINSTALL_OEM_INFA} i(r1, 1, 0) .r3"
These calls don't work. :-(
I don't even get a return value except for "error" from GetLastError....
I've added Dumpstate::debug calls and MessageBox output to see stack and variables,
but it seems that the call is aborted before setting any return code.
Can somebody point out what I'm doing wrong?
I do have "SetPluginUnload alwaysoff" and "SetPluginUnload manual" and "System::Free 0"
of course, globally/in the respective section.
If I get this working I can start work on a NSIS module implementing/using
Microsoft DIF (Driver Installation Framework), which would really simplify
driver installations.
Here are the relevant code snippets:
Function RegisterInfCall in section:
;prototype BOOL WINAPI SetupCopyOEMInf(
; PCTSTR SourceInfFileName,
; PCTSTR OEMSourceMediaLocation,
; DWORD OEMSourceMediaType,
; DWORD CopyStyle,
; PTSTR DestinationInfFileName,
; DWORD DestinationInfFileNameSize,
; PDWORD RequiredSize,
; PTSTR DestinationInfFileNameComponent
😉;
Exch $0 ; passed path to inf file
Push $1
Push $2
Push $3
SetOutPath $SYSDIR
${GetFileName} $0 $1 ; get filename part of path
Dumpstate::debug
System::Call '${SETUP_COPY_OEM_INFA} (r0,,0, 2, .r2, ${NSIS_MAX_STRLEN},, )'
Dumpstate::debug
Call CheckError
; return code is in $3
MessageBox MB_ICONINFORMATION|MB_OK "SetupCopyOEMInf ($0 / $2) returned $3 "
IntCmp $3 0 WriteToReg
StrCpy $2 ""
WriteToReg:
; result is in $2
WriteRegStr ${NSIS_REGISTRY_ROOT} "Software\${OEM}\${PRODUCT}" "$1" "$2"
Pop $3
Pop $2
Pop $1
Exch $0
FunctionEnd
Function un.RegisterInf
;prototype BOOL SetupUninstallOEMInf(
; PCWSTR InfFileName,
; DWORD Flags,
; PVOID Reserved
😉;
Exch $0 ; passed path inf file name
Push $1
Push $2
Push $3
; result is in $1
ReadRegStr $1 ${NSIS_REGISTRY_ROOT} "${NSIS_REGISTRY_PRODUCTPATH}" "$0"
${un.GetFileName} $1 $2 ; get filename part of path
StrCmp $OSVersion 'W2K' Case_W2K
System::Call "${SETUP_UNINSTALL_OEM_INFA} i(r1, 1, 0) .r3"
; return code is in $3
MessageBox MB_ICONINFORMATION|MB_OK "SetupUninstallOEMInfA ($0 / $1) returned $3 "
StrCpy $0 $3
IntCmp $3 0 Done
goto Done
Case_W2K:
StrCpy $0 ""
SetFileAttributes $1 FILE_ATTRIBUTE_NORMAL
Delete $1
IfErrors 0 Done
StrCpy $0 "1"
Done:
Pop $3
Pop $2
Pop $1
Exch $0
FunctionEnd
Function CheckError
Push $0
System::Call "Kernel32::GetLastError ()i ().r0"
Dumpstate::debug
MessageBox MB_ICONINFORMATION|MB_OK "Error code: $0 "
Pop $0
FunctionEnd
:
StrCpy $0 "$INSTDIR\${MY_DRIVERNAME}.inf"
Push $0
Call RegisterInf
Pop $R0
IntCmpU $R0 0 InfError InfError
: