[sword-svn] r81 - trunk/src/installer
bdrake at www.crosswire.org
bdrake at www.crosswire.org
Fri Dec 28 13:16:18 MST 2007
Author: bdrake
Date: 2007-12-28 13:16:16 -0700 (Fri, 28 Dec 2007)
New Revision: 81
Modified:
trunk/src/installer/doInstall.cpp
Log:
First fully working version of installer. Needs additional tests writing in. Cannot delete, and won't handle lexdicts properly. (Why is the path string different in these?)
Modified: trunk/src/installer/doInstall.cpp
===================================================================
--- trunk/src/installer/doInstall.cpp 2007-12-28 07:20:09 UTC (rev 80)
+++ trunk/src/installer/doInstall.cpp 2007-12-28 20:16:16 UTC (rev 81)
@@ -2,6 +2,7 @@
#include "Form1.h"
#include <tchar.h>
#include <rapi.h>
+#include <windows.h>
using namespace SRInstallMGR;
using namespace System;
@@ -42,15 +43,12 @@
TCHAR wszSrcFile[MAX_PATH];
WCHAR tszDestFile[MAX_PATH];
WCHAR searchPath[MAX_PATH];
-
-
HANDLE hSrc, hDest;
BYTE Buffer[10000];
DWORD dwNumRead, dwNumWritten;
wcscpy_s(searchPath, Path);
- wcscat_s(searchPath, L"*");
-
+ wcscat_s(searchPath, L"*");
if(!CeFindAllFiles(searchPath, FAF_ATTRIBUTES | FAF_NAME, &foundCount, &findDataArray)) {
_tprintf( TEXT("*** CeFindAllFiles failed. ***\n"));
return(NULL);
@@ -81,9 +79,6 @@
// to have installed into two different locations - really!
*********************************************************************************/
- // wprintf( TEXT("%s%s\n"),Path, findDataArray[i].cFileName); // for debugging
- // TODO - now add the filename to a list ready for later stage
- // copy the file from Ce device to Pc
wcscpy_s(wszSrcFile, Path);
wcscat_s(wszSrcFile, findDataArray[i].cFileName);
wcscpy_s( tszDestFile, TEXT("mods.d\\"));
@@ -91,18 +86,16 @@
hSrc = CeCreateFile(wszSrcFile, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hSrc) {
- MessageBox::Show("Sorry, I'm struggling to open a file on your device.", "Process Failed",
- MessageBoxButtons::OK);
- Application::Exit();
+ MessageBox::Show("Sorry, I'm struggling to open a file on your device.", "Process Failed",
+ MessageBoxButtons::OK);
+ Application::Exit();
}
hDest = CreateFile(tszDestFile, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hDest) {
- // NOTE: there has to be an existing 'mods.d' directory
- // in your working directory on the host
- MessageBox::Show("Sorry, I can't seem to write files to your PC. Do you have a mods.d directory where you put me?", "Process Failed",
+ MessageBox::Show("Sorry, I can't seem to write files to your PC. Do you have a mods.d directory where you put me?", "Process Failed",
MessageBoxButtons::OK);
- Application::Exit();
+ Application::Exit();
}
if (CeReadFile(hSrc, &Buffer, sizeof(Buffer), &dwNumRead, NULL)) {
if (!WriteFile(hDest, &Buffer, dwNumRead, &dwNumWritten, NULL)) {
@@ -119,7 +112,7 @@
} // else if ((stristr(wstrtostr ......
// no longer pointing to a mods.d directory, so close file handles
if (hSrc){
- CeCloseHandle( hSrc);
+ CeCloseHandle(hSrc);
hSrc = NULL;
}
if (hDest){
@@ -129,15 +122,70 @@
} // for(UINT i = 0; ........
if (findDataArray)
RapiFreeBuffer(findDataArray);
- return (swordPath);
+ return (swordPath); // TODO may need to make swordPath global .........
}
+void CopyOver (LPCWSTR sourceName, LPCWSTR destName) {
+ HANDLE hSrc, hCeDest;
+ BYTE Buffer[10000];
+ DWORD dwNumRead, dwNumWritten;
+ hSrc = CreateFile(sourceName, GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (INVALID_HANDLE_VALUE == hSrc) {
+ MessageBox::Show("Sorry, I can't seem able to open source/host file on PC", "Process Failed",
+ MessageBoxButtons::OK);
+ Application::Exit();
+ }
+ hCeDest = CeCreateFile(destName, GENERIC_WRITE, FILE_SHARE_READ,
+ NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (INVALID_HANDLE_VALUE == hCeDest ) {
+ MessageBox::Show("Sorry, I can't seem able to open destination file file on your mobile device for writing", "Process Failed",
+ MessageBoxButtons::OK);
+ Application::Exit();
+ }
+ do {
+ if (ReadFile(hSrc, &Buffer, sizeof(Buffer), &dwNumRead, NULL)) {
+ if (!CeWriteFile(hCeDest, &Buffer, dwNumRead, &dwNumWritten, NULL)) {
+ MessageBox::Show("Sorry, I can't seem able to open the file on your mobile device for writing", "Process Failed",
+ MessageBoxButtons::OK);
+ Application::Exit();
+ }
+ }
+ else {
+ MessageBox::Show("Sorry, I can't seem able to open the source file file on your mobile device for writing", "Process Failed",
+ MessageBoxButtons::OK);
+ Application::Exit();
+ }
+ } while (dwNumRead);
+ if (hCeDest){
+ CeCloseHandle(hCeDest);
+ hCeDest = NULL;
+ }
+ if (hSrc){
+ CloseHandle (hSrc);
+ hSrc = NULL;
+ }
+}
+
+// delete function still to be written
+ /*
+ // here is a method to use for removing a single file
+ char FileToDelete[]= "mods.d\\gill.conf";
+ char *f2del = FileToDelete;
+ String^ ptr = System::Runtime::InteropServices::Marshal::PtrToStringAnsi((IntPtr)f2del);
+ // I don't have a clue how the above line works, but it does!
+ File::Delete(ptr);
+ */
+
+
const char* doInstall() {
char swPath[MAX_PATH];
const char* swordPathString = swPath;
HANDLE modFile;
HANDLE hFile; // Handle to directory
+ HANDLE modDir;
WIN32_FIND_DATA FileInformation; // File information
+ WIN32_FIND_DATA modFileInformation; // File information
DWORD BytesToRead;
DWORD BytesRead = 0;
BOOL isopen = FALSE;
@@ -149,116 +197,170 @@
char *modName = m2Path;
char longstr[10000];
LPVOID lpBuffer = longstr;
+ TCHAR wszSrcFile[MAX_PATH];
+ WCHAR tszCEDestFile[MAX_PATH];
const char *pathstr;
-
RAPIINIT ri = { sizeof(RAPIINIT) };
- if ( SUCCEEDED(CeRapiInitEx(&ri)))
- {
+ if ( SUCCEEDED(CeRapiInitEx(&ri))) {
// wait for 10 seconds for the connection...
if ( (WaitForSingleObject(ri.heRapiInit, 10000) == WAIT_OBJECT_0) &&
- SUCCEEDED(ri.hrRapiInit) ) {
- TCHAR* swordPath = PrintDirectory( L"\\", 0);
- if (*swordPath != NULL)
- swordPathString = wstrtostr(swordPath);
- // we now have TCHAR *swordPath and char *swordPathString
- // both holding the full sword path on the mobile device
- // and the mods.d directory on the pc now containing copies of
- // all the mods.d files that are on the mobile device
- CeRapiUninit();
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
- ZeroMemory( &pi, sizeof(pi) );
- // Start the child process - InstallManager.
- if( !CreateProcess( TEXT("InstallManager.exe"), TEXT("InstallManager.exe"), // Command line.
- NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi )) {
- MessageBox::Show("Sorry, I could not activate InstallManager", "Process Failed",
- MessageBoxButtons::OK);
- Application::Exit();
- }
- // Wait until InstallManager exits.
- WaitForSingleObject( pi.hProcess, INFINITE );
- // Close process and thread handles.
- CloseHandle( pi.hProcess );
- CloseHandle( pi.hThread );
+ SUCCEEDED(ri.hrRapiInit) ) {
+ // CreateDirectory does not have a problem if the directory
+ // named exists already
+ Directory::CreateDirectory( "mods.d" );
+ Directory::CreateDirectory( "modules" );
+ TCHAR* swordPath = PrintDirectory( L"\\", 0);
+ // CeRapiUninit();
+ if (*swordPath != NULL)
+ swordPathString = wstrtostr(swordPath);
+ // we now have TCHAR *swordPath and char *swordPathString
+ // both holding the full sword path from the mobile device
+ // and the mods.d directory on the pc is now containing copies
+ // of all the mods.d files that are on the mobile device
+ // plus we definitely have a mods.d and modules directory as
+ // these are not checked for by InstallManager (It bombs out!).
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof(si);
+ ZeroMemory( &pi, sizeof(pi) );
+ // Start the child process - InstallManager.
+ if( !CreateProcess( TEXT("InstallManager.exe"), TEXT("InstallManager.exe"), // Command line.
+ NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi )) {
+ MessageBox::Show("Sorry, I could not activate InstallManager", "Process Failed",
+ MessageBoxButtons::OK);
+ Application::Exit();
+ }
+ // Wait until InstallManager exits.
+ WaitForSingleObject( pi.hProcess, INFINITE );
+ // Close process and thread handles.
+ CloseHandle( pi.hProcess );
+ CloseHandle( pi.hThread );
- hFile = ::FindFirstFile(TEXT("mods.d\\*.conf"), &FileInformation);
- if(hFile != INVALID_HANDLE_VALUE)
- {
- do {
- // MessageBox::Show("in while loop now", "Testing",
- // MessageBoxButtons::OK);
- // each .conf file in mods.d comes here with name etc
- wcscpy ( name, TEXT("mods.d\\"));
- wcscat (name, FileInformation.cFileName);
- BytesToRead = sizeof(longstr)-1;
- modFile = CreateFile(name, GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (INVALID_HANDLE_VALUE == modFile) {
- MessageBox::Show("Sorry, I can't seem to read files in your mods.d directory. Do you have a mods.d directory where you put me?", "Process Failed",
- MessageBoxButtons::OK);
- Application::Exit();
- return(NULL);
- }
- // read the entire .conf file into our buffer - biggest I know of
- // now is a 5k .conf, so I've gone for a 10,000 byte buffer ....
-
- isopen = ReadFile(modFile, &longstr, BytesToRead, &BytesRead, NULL);
- // we ought to check for success 'if isopen' or something
- CloseHandle(modFile);
- pathstr = stristr (longstr, "DataPath=.");
- if (!pathstr){
- MessageBox::Show("Failed to make string match for DataPath=.", "Leaving now",
+ hFile = FindFirstFile(TEXT("mods.d\\*.conf"), &FileInformation);
+ if(hFile != INVALID_HANDLE_VALUE)
+ {
+ do {
+ // each .conf file in mods.d comes here with name etc
+ wcscpy ( name, TEXT("mods.d\\"));
+ wcscat (name, FileInformation.cFileName);
+ BytesToRead = sizeof(longstr)-1;
+ modFile = CreateFile(name, GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (INVALID_HANDLE_VALUE == modFile) {
+ MessageBox::Show("Sorry, I can't seem to read files in your mods.d directory. Do you have a mods.d directory where you put me?", "Process Failed",
MessageBoxButtons::OK);
Application::Exit();
+ return(NULL);
+ }
+ // read the entire .conf file into our buffer - biggest I know of
+ // now is a 5k .conf, so I've gone for a 10,000 byte buffer ....
+
+ isopen = ReadFile(modFile, &longstr, BytesToRead, &BytesRead, NULL);
+ // we ought to check for success 'if isopen' and do something
+ if (modFile){
+ CloseHandle(modFile);
+ modFile = NULL;
+ }
+ pathstr = stristr (longstr, "DataPath=.");
+ if (!pathstr){
+ MessageBox::Show("Failed to make string match for DataPath=.", "Leaving now",
+ MessageBoxButtons::OK);
+ Application::Exit();
+ }
+ pathstr+=10; // move pointer to end of 'DataPath=.'
+ strcpy (modulePath, "");// this will need to be the swordPath
+ int i = 0;
+ int p = (strlen(modulePath));
+ p--;
+ while (*(pathstr+i) != 10 && *(pathstr+i) != 13) { // some confs have cr/lf and some only lf (why?)
+ *(modulePath+p++) = *(pathstr+i);
+ i++;
+ }
+ // --p; // if we don't want trailing slash
+ *(modulePath+p) = 0; // at end of trailing slash in pathstring
+ // TODO - lexdicts are handled differently in pathing
+ char *tmp = modulePath;
+ while (*(tmp++))if (*tmp == 47) *tmp = 92; // change '/' into '\'
+ String^ ptr = System::Runtime::InteropServices::Marshal::PtrToStringAnsi((IntPtr)modulePath);
+ // I don't have a clue how the above line works, but it does!
+ if (Directory::Exists(ptr)) {
+ // if there is no directory under 'modules' skip this
+ strcat (modulePath, "*");
+ int len = strlen(modulePath)+1;
+ wchar_t *wText = new wchar_t[len];
+ memset(wText,0,len);
+ ::MultiByteToWideChar(CP_ACP, NULL, modulePath, -1, wText,len);
+ modDir = FindFirstFile(wText, &modFileInformation);
+ if(modDir == INVALID_HANDLE_VALUE){
+ MessageBox::Show("Sorry, I can't seem to read files from your newly downloaded module.", "Process Failed",
+ MessageBoxButtons::OK);
+ Application::Exit();
+ }
+ len = wcslen (wText);
+ len --;
+ *(wText+len) = 0;
+ len = strlen(modulePath);
+ *(modulePath +len - 1) = 0;
+ do { // copy each of module files onto mobile device followed by .conf
+ // create the path on the mobile device here
+ wcscpy_s (tszCEDestFile, swordPath);
+ wcscat_s (tszCEDestFile, wText); // full path to create
+ CeCreateDirectory(tszCEDestFile, 0);
+ // TODO - should do a check for creation here
+ // file copy will fail else
+ wcscpy_s(wszSrcFile, wText);
+ wcscat_s(wszSrcFile, modFileInformation.cFileName);
+ char destMP[MAX_PATH];
+ char *destModPath = destMP;
+ strcpy (destModPath, swordPathString);
+ strcat (destModPath, modulePath);
+ len = strlen(destModPath) + 1;
+ wchar_t *wDestFile = new wchar_t[len];
+ memset(wDestFile,0,len);
+ ::MultiByteToWideChar(CP_ACP, NULL, destModPath, -1, wDestFile,len);
+ wcscpy_s( tszCEDestFile, wDestFile);
+ wcscat_s( tszCEDestFile, modFileInformation.cFileName);
+ if(!(modFileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { // directory found
+ CopyOver (wszSrcFile, tszCEDestFile);
+ } // if(!(modFileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
+ }while(FindNextFile(modDir, &modFileInformation) == TRUE);
+ if (modDir){
+ FindClose (modDir);
+ modDir = NULL;
+ }
+ // now copy over the module .conf file
+ wcscpy_s (tszCEDestFile, swordPath);
+ wcscat_s (tszCEDestFile, name);
+ CopyOver (name, tszCEDestFile);
+ } // if (Directory::Exists(ptr
+ }while(FindNextFile(hFile, &FileInformation) == TRUE);
+ }
+ if (modFile){
+ CloseHandle(modFile);
+ modFile = NULL;
}
- pathstr+=10;
- strcpy (modulePath, "");// this will need to be the swordPath
- int i = 0;
- int p = (strlen(modulePath));
- p--;
- while (*(pathstr+i) != 10 && *(pathstr+i) != 13) { // some confs have cr/lf and some only lf (why?)
- *(modulePath+p++) = *(pathstr+i);
- i++;
+ if (modDir){
+ FindClose (modDir);
+ modDir = NULL;
+ } // Close handles
+ if (hFile){
+ FindClose(hFile);
+ hFile = NULL;
}
-// --p; // if we don't want trailing slash
- *(modulePath+p) = 0; // at end of trailing slash in pathstring
- // TODO - lexdicts are handled differently in pathing
-
-
- // TODO - copy each module .conf and files to mobile device
- // only if there are files for that module in modules directory
-
-
- /*
- // here is the method I'll use for removing a single file
- char FileToDelete[]= "mods.d\\gill.conf";
- char *f2del = FileToDelete;
- String^ ptr = System::Runtime::InteropServices::Marshal::PtrToStringAnsi((IntPtr)f2del);
- // I don't have a clue how the above line works, but it does!
- File::Delete(ptr);
- */
-
- }while(::FindNextFile(hFile, &FileInformation) == TRUE);
- }
- ::FindClose(hFile); // Close handle
- // now remove all the files from the pc
- Directory::Delete( "mods.d", true );
- Directory::Delete( "modules", true );
- // but leave with the directories in place for next time - or could
- // move the creates to the beginning of this function - maybe tidier?
- Directory::CreateDirectory( "mods.d" );
- Directory::CreateDirectory( "modules" );
- return (swordPathString);
- }
+ CeRapiUninit();
+ // now remove all the files from the pc
+ Directory::Delete( "mods.d", true );
+ Directory::Delete( "modules", true );
+ return (swordPathString);
+ } // if ( (WaitForSingleObject(ri.heRapiInit .....
else {
MessageBox::Show("Sorry, I could not connect to your mobile device", "CeRapiInit failed",
MessageBoxButtons::OK);
CeRapiUninit();
Application::Exit();
}
- Application::Exit();
+ // Application::Exit();
if ( CeRapiInit() != E_FAIL ) {
}
else {
@@ -267,8 +369,8 @@
CeRapiUninit();
Application::Exit();
}
- Application::Exit();
- }
+ // Application::Exit();
+ } // if ( SUCCEEDED(CeRapiInitEx
Application::Exit();
return(0); // can't get here - but avoids warning
}
More information about the sword-cvs
mailing list