[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