ruby/wince/wince.c

584 строки
11 KiB
C

/***************************************************************
wince.c
author : uema2
date : Nov 30, 2002
You can freely use, copy, modify, and redistribute
the whole contents.
***************************************************************/
#include <windows.h>
#include <tchar.h>
#include "wince.h"
/* global for GetCommandLineA */
char *_commandLine;
extern char _currentdir[];
/* make up Win32API except wce_* functions. */
DWORD GetModuleFileNameA(
HMODULE hModule, LPSTR lpFileName,
DWORD size )
{
LPWSTR lpFileNameW;
LPSTR mb;
size_t ret;
if( size==0 ) return 0;
lpFileNameW = (LPWSTR)malloc( size*sizeof(wchar_t) );
ret = GetModuleFileNameW( hModule, lpFileNameW, size );
mb = wce_wctomb(lpFileNameW);
strcpy(lpFileName, mb);
free(mb);
free(lpFileNameW);
return ret;
}
#if _WIN32_WCE < 300
FARPROC GetProcAddressA(HMODULE hModule, LPCSTR lpProcName)
{
FARPROC p;
LPWSTR lpwProcName;
lpwProcName = wce_mbtowc( lpProcName );
p = GetProcAddressW( hModule, lpwProcName );
free( lpwProcName );
return p;
}
#endif
char * GetCommandLineA(void)
{
return _commandLine;
}
/* this is not Win32API. GetCommandLineA helper. */
void wce_SetCommandLine(LPCWSTR wcmd)
{
char* acmd;
acmd = wce_wctomb( wcmd );
_commandLine = (char*)malloc( strlen(acmd)+5 );
sprintf( _commandLine, "ruby %s", acmd );
free(acmd);
}
/* this is not Win32API. GetCommandLineA helper. */
void wce_FreeCommandLine(void)
{
free(_commandLine);
_commandLine = NULL;
}
/* I have no idea how to replace this. */
BOOL GetProcessTimes(HANDLE hprocess,
LPFILETIME lpCreationTime, LPFILETIME lpExitTime,
LPFILETIME lpKernelTime, LPFILETIME lpUserTime)
{
return 0;
}
/* -------------- file attributes functions. ------------------- */
DWORD GetFileAttributesA(LPCSTR lpFileName)
{
LPWSTR lpwFileName;
DWORD dw;
lpwFileName = wce_mbtowc(lpFileName);
dw = GetFileAttributesW(lpwFileName);
free(lpwFileName);
return dw;
}
BOOL SetFileAttributesA(
LPCSTR lpFileName, DWORD attributes)
{
LPWSTR lpwFileName;
BOOL b;
lpwFileName = wce_mbtowc(lpFileName);
b = SetFileAttributesW(lpwFileName, attributes);
free(lpwFileName);
return b;
}
/* --------------- move and remove functions. ------------------- */
BOOL MoveFileA(LPCSTR fn1, LPCSTR fn2)
{
LPWSTR wfn1, wfn2;
BOOL b;
wfn1 = wce_mbtowc(fn1);
wfn2 = wce_mbtowc(fn2);
b = MoveFileW(wfn1, wfn2);
free(wfn1);
free(wfn2);
return 0;
}
BOOL MoveFileEx(LPCSTR oldname, LPCSTR newname, DWORD dwFlags)
{
LPWSTR woldname, wnewname;
BOOL b;
woldname = wce_mbtowc(oldname);
wnewname = wce_mbtowc(newname);
if( (dwFlags&MOVEFILE_REPLACE_EXISTING)!=0 )
DeleteFileW( wnewname );
b = MoveFileW( woldname, wnewname );
free(woldname);
free(wnewname);
return b;
}
BOOL DeleteFileA(LPCSTR path)
{
LPWSTR wpath;
BOOL b;
wpath = wce_mbtowc(path);
b = DeleteFileW(wpath);
free(wpath);
return 0;
}
/* --------------- EnvironmentVariable functions. ----------------- */
DWORD GetEnvironmentVariable(
LPCSTR name, LPSTR value, DWORD size)
{
/* use registry instead of "environment valuable". */
HKEY hk;
LONG lret;
LPBYTE lpData;
DWORD dwType=REG_SZ, cbData;
TCHAR buf[MAX_PATH]={0};
LPWSTR wname;
LPSTR avalue;
lret = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
_T("Software\\ruby_mswince"),
0, KEY_QUERY_VALUE, &hk );
if ( lret != ERROR_SUCCESS )
{
strcpy( value, "" );
return 0;
}
lpData = (LPBYTE)buf;
cbData = MAX_PATH*sizeof(*buf);
wname = wce_mbtowc( name );
lret = RegQueryValueEx( hk, wname,
NULL, &dwType, lpData, &cbData );
RegCloseKey( hk );
if ( lret != ERROR_SUCCESS )
{
strcpy( value, "" );
free( wname );
return 0;
}
avalue = wce_wctomb( (LPCTSTR)lpData );
strcpy( value, avalue );
free( avalue );
free( wname );
return strlen(value);
}
BOOL SetEnvironmentVariable(LPCSTR name, LPCSTR value)
{
/* use registry instead of "environment valuable". */
HKEY hk;
LONG lret;
LPBYTE lpData;
DWORD ret, dwType=REG_SZ, cbData;
LPWSTR wname, wvalue;
lret = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
_T("Software\\ruby_mswince"),
0, _T(""), 0,
0, NULL, &hk, &ret );
if( lret != ERROR_SUCCESS )
return FALSE;
wname = wce_mbtowc(name);
wvalue = wce_mbtowc(value);
lpData = (LPBYTE)wvalue;
cbData = (wcslen(wvalue) + 1) * sizeof(*wvalue);
lret = RegSetValueEx( hk, wname,
0, dwType, lpData, cbData );
RegCloseKey( hk );
free(wname);
free(wvalue);
return lret == ERROR_SUCCESS;
}
LPVOID GetEnvironmentStrings(VOID)
{
return NULL;
}
BOOL FreeEnvironmentStrings(LPSTR lpszEnvironmentBlock)
{
return FALSE;
}
/* DuplicateHandle, LockFile, etc... */
/* I have no idea... */
BOOL GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,
DWORD dwProcessGroupID)
{
return 0;
}
BOOL DuplicateHandle(
HANDLE source_process, HANDLE source,
HANDLE dest_process, HANDLE *dest,
DWORD access, BOOL inherit, DWORD options)
{
return 0;
}
BOOL LockFile(HANDLE hFile,
DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh)
{
return FALSE;
}
BOOL LockFileEx(HANDLE hFile,
DWORD dwFlags, DWORD dwReserved,
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh,
LPOVERLAPPED lpOverlapped)
{
return FALSE;
}
BOOL UnlockFile( HFILE hFile,
DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh)
{
return FALSE;
}
BOOL UnlockFileEx(HANDLE hFile,
DWORD dwReserved, DWORD nNumberOfBytesToUnlockLow,
DWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped)
{
return FALSE;
}
/* --------------------- etc, etc, etc... ----------------------- */
BOOL GetVersionExA(OSVERSIONINFOA *v)
{
OSVERSIONINFOW wv;
BOOL b;
LPSTR mb;
b = GetVersionExW(&wv);
mb = wce_wctomb(wv.szCSDVersion);
strcpy( v->szCSDVersion, mb );
free(mb);
return b;
}
DWORD WaitForMultipleObjectsEx(DWORD count,
const HANDLE *handles, BOOL wait_all,
DWORD timeout, BOOL alertable)
{
return WaitForMultipleObjects(
count, handles, wait_all,
timeout );
}
BOOL CreateProcessA(LPCSTR appname, LPCSTR commandline,
LPSECURITY_ATTRIBUTES att, LPSECURITY_ATTRIBUTES threadatt,
BOOL bOpt, DWORD dwFlag, LPVOID lpEnv, LPSTR dir,
LPSTARTUPINFO lpsi, LPPROCESS_INFORMATION lppi)
{
LPWSTR wappname, wcommandline, wdir;
BOOL b;
wappname = wce_mbtowc(appname);
wcommandline = wce_mbtowc(commandline);
wdir = wce_mbtowc(dir);
b = CreateProcessW(wappname, wcommandline,
att, threadatt, bOpt, dwFlag, lpEnv,
wdir, lpsi, lppi);
free(wappname);
free(wcommandline);
free(wdir);
return b;
}
HANDLE CreateEventA(SECURITY_ATTRIBUTES *sa,
BOOL manual_reset, BOOL initial_state, LPCSTR name)
{
HANDLE h;
LPWSTR wname;
wname = wce_mbtowc(name);
h = CreateEventW(sa, manual_reset,
initial_state, wname);
free(wname);
return h;
}
DWORD FormatMessageA(DWORD dwFlags, LPCVOID lpSource,
DWORD dwMessageId, DWORD dwLanguageId, LPSTR lpBuffer,
DWORD nSize, va_list* args)
{
DWORD dw;
LPWSTR lpWBuffer;
lpWBuffer = wce_mbtowc(lpBuffer);
dw = FormatMessageW( dwFlags, lpSource,
dwMessageId, dwLanguageId,
lpWBuffer, nSize, (va_list*)args );
free(lpWBuffer);
return dw;
}
/*---------------- FindFirstFile, FindNextFile ------------------ */
HANDLE FindFirstFileA(LPCSTR path,
WIN32_FIND_DATAA *data)
{
LPWSTR wpath;
LPSTR mb;
HANDLE h;
WIN32_FIND_DATAW wdata;
wpath = wce_mbtowc(path);
h = FindFirstFileW( wpath, &wdata );
free(wpath);
mb = wce_wctomb( wdata.cFileName );
strcpy( data->cFileName, mb );
free(mb);
return h;
}
BOOL FindNextFileA(HANDLE handle,
WIN32_FIND_DATAA *data)
{
BOOL b;
WIN32_FIND_DATAW wdata;
LPSTR mb1;
b = FindNextFileW(handle, &wdata);
mb1 = wce_wctomb( wdata.cFileName );
strcpy( data->cFileName, mb1 );
free(mb1);
return b;
}
/* CreateFile doesn't support SECURITY_ATTRIBUTES in WinCE. */
/* it must be NULL. */
HANDLE CreateFileA(LPCSTR filename, DWORD access,
DWORD sharing, LPSECURITY_ATTRIBUTES sa,
DWORD creation, DWORD attributes, HANDLE template)
{
LPWSTR wfilename;
HANDLE h;
wfilename = wce_mbtowc(filename);
h = CreateFileW(wfilename, access, sharing,
NULL, creation, 0, NULL);
free(wfilename);
return 0;
}
/* ---------------- CharNext, CharPrev. ---------------------*/
LPSTR CharNextA(LPCSTR a)
{
char *p=(char *)a;
if( TRUE==IsDBCSLeadByteEx(CP_ACP, (BYTE)*a) )
p+=2;
else
p++;
return p;
}
LPSTR CharPrevA(LPCSTR start, LPCSTR ptr)
{
if( start==ptr ) return (LPSTR)start;
else if( start+1==ptr ) return (LPSTR)start;
else if( TRUE==IsDBCSLeadByteEx(CP_ACP, (BYTE)*(ptr-2)) )
return (LPSTR)(ptr-2);
else
return (LPSTR)(ptr-1);
}
/* WinCE doesn't have "drives". */
DWORD GetLogicalDrives(VOID)
{
return 0;
}
/* WinCE doesn't have "user name". */
BOOL GetUserName(LPSTR lpBuffer, LPDWORD nSize)
{
return 0;
}
/*------------------- LoadLibrary -----------------------*/
HINSTANCE LoadLibraryA(LPCSTR libname)
{
HINSTANCE h;
LPWSTR wlibname;
// if starts ".\", replace current directory.
// wlibname = wce_replaceRelativeDir(libname);
wlibname = wce_mbtowc(libname);
h = LoadLibraryW(wlibname);
free(wlibname);
return h;
}
HINSTANCE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile,
DWORD dwFlags)
{
HINSTANCE h;
LPWSTR wlibname;
wlibname = wce_mbtowc(lpLibFileName);
// wlibname = wce_replaceRelativeDir(lpLibFileName);
#if _WIN32_WCE < 300
h = LoadLibraryW(wlibname);
#else
h = LoadLibraryExW(wlibname, hFile, dwFlags);
#endif
free(wlibname);
return h;
}
/* WinCE doesn't have "CreatePipe". */
BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe,
LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)
{
return FALSE;
}
/* WinCE doesn't have "Standard Devices". */
HANDLE GetStdHandle(DWORD nStdHandle)
{
return NULL;
}
BOOL SetStdHandle(DWORD nStdHandle, HANDLE h)
{
return FALSE;
}
#if _WIN32_WCE < 300
VOID ZeroMemory(PVOID p, DWORD length)
{
memset(p,0,length);
}
#endif
/* need in ruby/io.c. */
int ReadDataPending()
{
return 0;
}
/*---------------- helper functions. ---------------------------- */
FILE *wce_fopen( const char *fname, const char *mode )
{
TCHAR* tfname = wce_replaceRelativeDir(fname);
TCHAR* tmode = wce_mbtowc(mode);
FILE* fp = _tfopen(tfname, tmode);
free(tfname); free(tmode);
return fp;
}
void wce_SetCurrentDir()
{
WCHAR tbuf[MAX_PATH+1]={0};
WCHAR *tp;
char *buf;
GetModuleFileNameW( NULL, tbuf, MAX_PATH );
tp = _tcsrchr( tbuf, '\\' );
if( tp!=NULL ) *tp=_T('\0');
buf = wce_wctomb(tbuf);
strcpy( _currentdir, buf );
free(buf);
}
TCHAR *wce_replaceRelativeDir(const char* str)
{
TCHAR *tbuf;
if( 2<=strlen(str) && str[0]=='.' &&
(str[1]=='/' || str[1]=='\\') )
{
char *buf;
int len = strlen(str) + strlen(_currentdir);
buf = malloc( len+1 );
sprintf(buf, "%s%s", _currentdir, &str[1]);
tbuf = wce_mbtowc(buf);
free(buf);
}
else
tbuf = wce_mbtowc(str);
return tbuf;
}
/* char -> wchar_t */
wchar_t* wce_mbtowc(const char* a)
{
int length;
wchar_t *wbuf;
length = MultiByteToWideChar(CP_ACP, 0,
a, -1, NULL, 0);
wbuf = (wchar_t*)malloc( (length+1)*sizeof(wchar_t) );
MultiByteToWideChar(CP_ACP, 0,
a, -1, wbuf, length);
return wbuf;
}
/* wchar_t -> char */
char* wce_wctomb(const wchar_t* w)
{
DWORD charlength;
char* pChar;
charlength = WideCharToMultiByte(CP_ACP, 0, w,
-1, NULL, 0, NULL, NULL);
pChar = (char*)malloc(charlength+1);
WideCharToMultiByte(CP_ACP, 0, w,
-1, pChar, charlength, NULL, NULL);
return pChar;
}