Archive: Invoking RAPI functions with System.dll


Invoking RAPI functions with System.dll
Hi,

I am trying to copy a text file containing program settings to a Pocket PC device using RAPI. My problem is that nothing seems to work when I invoke the call. The script I am executing is below :

File C:\WINDOWS\system32\rapi.dll ; copy dll there

StrCpy $0 "$INSTDIR\swanRDASetup.txt\0"
StrCpy $1 "\My Documents\swanRDASetup.txt\0"
StrCpy $2 FALSE
System::Call 'rapi.dll::CeCopyFile(*l r0, *l r1, b r2) b .r3'
DetailPrint 'Return Value: "$3"'

System::Free 0

Is this the correct way to do this? The file is never copied across to the PDA and the return value is always empty! Is there an easier way to do this? Any help would be HUGELY appreciated!

Thanks in advance

Brian


BTW I realized that I needed to call System::Call 'rapi.dll::CeRapiInit() i r0'
before the CeCopyFile call, however it still doesn't work!

But this brings up another problem, in that the value returned from CeRapiInit is a HRESULT and I am not sure what type to map this to in NSIS?


Try this:


System::Call "rapi::CeRapiInit() i .r0"
System::Call "rapi::CeCopyFile(t '$INSTDIR\swanRDASetup.txt', \
t '\My Documents\swanRDASetup.txt', i 0) b .r0"

Hi Guys,

I figured out that what I was trying to do was completely wrong. The CeCopyFile procedure only copies a file from one place to another ON the PDA, not from the desktop to the PDA. The documentation on this procedure is not very clear. The correct way to copy a file from the PC to the PDA is as follows :

Function createSettingsFile
;Init RAPI

;----------------------
;Dll Call Structure
;
;HRESULT CeRapiInit(void);
System::Call "rapi::CeRapiInit() i .r0"

;Create the file on the PDA

;----------------------
;Dll Call Structure
;
;HANDLE CeCreateFile(
; LPCWSTR lpFileName,
; DWORD dwDesiredAccess,
; DWORD dwShareMode,
; LPSECURITY_ATTRIBUTES lpSecurityAttributes,
; DWORD dwCreationDisposition,
; DWORD dwFlagsAndAttributes,
; HANDLE hTemplateFile
;);
;
; Access Mode Values :
; GENERIC_READ = 0x80000000;
; GENERIC_WRITE = 0x40000000;
;
; Creation Disposition Value :
; CREATE_NEW = 1;
; CREATE_ALWAYS = 2;
; OPEN_EXISTING = 3;
;
; Flag and attribute values
; FILE_ATTRIBUTE_NORMAL = 0x80;
; FILE_ATTRIBUTE_DIRECTORY = 0x10;
; FILE_ATTRIBUTE_TEMPORARY = 0x100;

System::Call "rapi::CeCreateFile(w '\swanRDASetup.txt', \
i 0x80000000|0x40000000, \
i 0, i 0, i 2, \
i 0x80, i 0) i .r10"

;Write your data across. Can be done in a loop etc.
StrCpy $1 'blah=$0$\r$\n'
StrLen $2 $1

;----------------------
;Dll Call Structure
;
;BOOL CeWriteFile(
; HANDLE hFile,
; LPCVOID lpBuffer,
; DWORD nNumberOfBytesToWrite,
; LPDWORD lpNumberOfBytesWritten,
; LPOVERLAPPED lpOverlapped
;);
System::Call "rapi::CeWriteFile(i r10., t r1, i r2, i 0, i 0) i .r11"

;----------------------
;Dll Call Structure
;
;BOOL CeCloseHandle(
; HANDLE hObject
;);

;Close the file on the PDA
System::Call "rapi::CeCloseHandle(i r10) i .r1"

System::Free 0
FunctionEnd

Rapi and NSIS
Hello,

I have seen the example on NSIS Web site about copyng file to PDA. My problem is that I would like to create a directory and, eventhough I have modified that example, I cannot reach out this.
May somebody guide me? I would like to create, and delete directories, or maybe move it, and also files, from the installer.

Thanks very much.
Ezequiel.


also... Is it possible in the function described by Gurrie to "pass" the file name of the file to create, as a parameter? Because there it's hardcoded.
Thanks!


I would recommend reading the RAPI documentation, which can be found here.

http://msdn.microsoft.com/library/de...IReference.asp


I wanted to know if someone finally found the answer, bcause I need to make an installer which unzip a ZIP file on the PDA SDCard, and then run a CAB file.

So, can anyone tell me where to find the path to the memory card from the Desktop ?


There are few relevant articles in the wiki. They're all under the PDA category.

http://nsis.sourceforge.net/Category:PDA_Examples


I already read those articles, but they did not answer that kind of problem.

To have the path from the desktop to the PDA, I try to do :
${registry::Open} "HKCU\Software\Microsoft\Windows CE Services\Partners" "/V=0 /N=PnPDeviceId /T=REG_SZ /B=2" $R0
${registry::Find} "$R0" $n1 $n2 $n3 $n4
${Do}
${registry::Find} "$R0" $n1 $n2 $n3 $n4
${If} $n4 == BANNER
${ExitDo}
${EndIf}
${Loop}
${registry::Read} "HKCU\$n1" "PnPDeviceId" $R1 $R2
StrCpy $PDALocation $R1
${registry::Unload}

It seems to work, but the path returned do not work in the script however it works when I use it in the explorer.

And when I try examples given on the wiki, it does not work at all... :cry:

Has anybody an idea ?


Do not consider my previous post.

The fact is I do not know how work RAPI...

I try to create some directory, but it does not work.

System::Call "rapi::CeCreateDirectory(t '\$CeSDCardLocation\My Folder', i 0) i.r0"


When I try to copy a file with the code given on the wiki, I think I do not know how to make a loop to copy all data...


${Do}
FileRead $0 $1
${If} $1 == ""
${ExitDo}
${EndIf}
;Get the length of the string read
StrLen $2 $1
System::Call "rapi::CeWriteFile(i r0., t r1, i r2, i 0, i 0) i .r0"
${Loop}


I am sure all the file is read (I used MessageBox to verify $1 ^^)

Do anybody see any error ?
Is there any link to learn how to use RAPI with NSIS ?

And I would like to know why a simple CeCopyFile does not work ?

I don't get from your code if $0 is a handle to a file on the PC or on the PDA. You use it for both set of functions. There's an example in the wiki which writes files to the PDA and also an example that installs a program using a CAB.

As far as I know, that's the information available on RAPI. If those aren't enough, it'd be nice if you can create a new page with more details once you get a working example.