[Q] windows rt win32 programming(need help) - Windows 8 General

Hello
I have read http://forum.xda-developers.com/showthread.php?t=1944675,and Im able to to compile single cpp file using cl.exe with /D _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
Here are my questions:
1.how can I compile arm project by VS2012 IDE?
2.how can I create arm version lib such as gdi32.lib that doesnt come with VS2012?
Here is my win32 cretewindow example :
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "user32.lib")
#include <windows.h>
#include <string.h>
#include <iostream>
MainWndProc (HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
static HWND hwndButton = 0;
static HWND hEdit = 0;
static int cx, cy;
HDC hdc;
PAINTSTRUCT ps;
RECT rc;
switch (nMsg)
{
case WM_CREATE:
{
TEXTMETRIC tm;
hdc = GetDC (hwnd);
//SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
//GetTextMetrics (hdc, &tm);
cx = tm.tmAveCharWidth * 30;
cy = (tm.tmHeight + tm.tmExternalLeading) * 2;
ReleaseDC (hwnd, hdc);
hwndButton = CreateWindow (
"button",
"Click Here",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
0, 0, cx, cy,
hwnd,
(HMENU) 1,
((LPCREATESTRUCT) lParam)->hInstance,
NULL
);
hEdit = CreateWindow( //edit控件
"edit",
"create",
WS_VISIBLE|WS_CHILD|WS_BORDER/*|DT_CENTER*/|DT_VCENTER,
100,70,100,25,
hwnd,
NULL,
NULL,
NULL);
return 0;
break;
}
case WM_DESTROY:
PostQuitMessage (0);
return 0;
break;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
GetClientRect (hwnd, &rc);
rc.bottom = rc.bottom / 2;
DrawText (hdc, "Hello, World!", -1, &rc,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint (hwnd, &ps);
return 0;
break;
case WM_SIZE:
if (hwndButton &&
(wParam == SIZEFULLSCREEN ||
wParam == SIZENORMAL)
)
{
rc.left = (LOWORD(lParam) - cx) / 2;
rc.top = HIWORD(lParam) * 3 / 4 - cy / 2;
MoveWindow (
hwndButton,
rc.left, rc.top, cx, cy, TRUE);
}
break;
case WM_COMMAND:
if (LOWORD(wParam) == 1 &&
HIWORD(wParam) == BN_CLICKED &&
(HWND) lParam == hwndButton)
{
DestroyWindow (hwnd);
}
return 0;
break;
}
return DefWindowProc (hwnd, nMsg, wParam, lParam);
}
int WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
{
HWND hwndMain;
MSG msg;
WNDCLASSEX wndclass;
char*szMainWndClass = "WinTestWin";
memset (&wndclass, 0, sizeof(WNDCLASSEX));
wndclass.lpszClassName = szMainWndClass;
wndclass.cbSize = sizeof(WNDCLASSEX);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = MainWndProc;
wndclass.hInstance = hInst;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
//wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
RegisterClassEx (&wndclass);
hwndMain = CreateWindow (
szMainWndClass,
"Hello",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInst,
NULL
);
ShowWindow (hwndMain, nShow);
UpdateWindow (hwndMain);
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
its able to run on my surface. GetStockObject,SelectObject and GetTextMetrics is in gdi32.lib but i dont have it so the running exe looks strange after redraw.
Im a beginner .Please help.

windowsrtc said:
Hello
I have read http://forum.xda-developers.com/showthread.php?t=1944675,and Im able to to compile single cpp file using cl.exe with /D _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
Here are my questions:
1.how can I compile arm project by VS2012 IDE?
2.how can I create arm version lib such as gdi32.lib that doesnt come with VS2012?
Here is my win32 cretewindow example :
-Snip-
its able to run on my surface. GetStockObject,SelectObject and GetTextMetrics is in gdi32.lib but i dont have it so the running exe looks strange after redraw.
Im a beginner .Please help.
Click to expand...
Click to collapse
How are you running this on your surface?

netham45 said:
How are you running this on your surface?
Click to expand...
Click to collapse
I've not tried windowsrtc's code, but I've managed to run a basic Win32 executable (unmodified Visual Studio 2012 Win32 project template) using the technique described in http://forum.xda-developers.com/showthread.php?t=1944675. I can believe that the above code (with GDI calls commented out) would also run.
windowsrtc:
1) You can compile Win32 code for ARM by following the instructions here: http://stackoverflow.com/a/12347035/394331, then setting output platform to ARM in configuration manager.
2) You can generate a .lib from a .dll using the technique described here: http://adrianhenke.wordpress.com/2008/12/05/create-lib-file-from-dll/. I tried doing this for a couple of dlls (namely comdlg32 and comctl32), and managed to get the resulting code to compile, however the application would then fail to run. Manually trying to load these with LoadLibrary would also fail, so I assume this is due to the very low privilege level of the application.

peterdn said:
I've not tried windowsrtc's code, but I've managed to run a basic Win32 executable (unmodified Visual Studio 2012 Win32 project template) using the technique described in http://forum.xda-developers.com/showthread.php?t=1944675. I can believe that the above code (with GDI calls commented out) would also run.
Click to expand...
Click to collapse
I'm fairly sure that apps started with that method don't have permission to open forms. I couldn't get them to do anything.

netham45 said:
I'm fairly sure that apps started with that method don't have permission to open forms. I couldn't get them to do anything.
Click to expand...
Click to collapse
This is just a template Win32 project compiled with VS2012 running using that technique: http://i.imgur.com/04W5d.png
I don't think I did anything special, but I can upload the solution if you want to take a look.

I stand corrected. I wasn't able to get it to launch MS apps with forums in them (mstsc, notepad), so I assumed they didn't work.
Edit: Did you have to give the program any special permissions?
Edit 2: A blank Win32 project opens, but things like Notepad don't, odd.

netham45 said:
How are you running this on your surface?
Click to expand...
Click to collapse
app1 opens a cmd shell,and then I launch my exe.Thats all.
My exe shows a window and there is a textbox on it.

netham45 said:
Edit 2: A blank Win32 project opens, but things like Notepad don't, odd.
Click to expand...
Click to collapse
Even notepad uses dependencies beyond user32.dll and kernel32.dll, and so under that privilege level simply won't be allowed.

Related

RAPI problem writing registry key value

I am presently writing a RegEdit program to run on my PC and allow editing of the registry on the connected PPC. I have got to the point where I can read the entire registry and I am now implementing function to update the registry i.e. insert new key, delete key, add new Key Values etc...
The problem I have at the moment is trying to add a new value to an existing key. The function I have written so far to do this is as follows, but the call to CeRegSetValueEx(...) returns an error code 5!
Code:
//-----------------------------------------------------------------------------------
// Adds a new key value into the registry.
// // TO DO - add the data
int CRegEditDoc::AddNewKeyValue(HTREEITEM hParent, HKEY hRoot, LPTSTR lpszKey, LPTSTR lpszValueName, DWORD dwType)
{
USES_CONVERSION;
int nItem, rc;
HKEY hKey;
LPWSTR lpwszKey = T2W(lpszKey);
LPWSTR lpwszValueName = T2W(lpszValueName);
try
{
if (lstrlen (lpszKey))
{
if (m_rapi.CeRegOpenKeyEx (hRoot, lpwszKey, 0, 0, &hKey) != ERROR_SUCCESS)
{
return 0;
}
}
else
{
hKey = hRoot;
}
CString strValue = "my data";
LPWSTR lpwszData = T2W(strValue);
DWORD length = dim(lpwszData);
nItem = m_pRightView->GetListCtrl().GetItemCount();
if (m_rapi.CeRegSetValueEx(hKey, lpwszValueName, 0, dwType, (LPBYTE)lpwszData, length*2) != ERROR_SUCCESS) // last 2 lpData, szie in bytes of data.
{
HRESULT hResult = m_rapi.CeRapiGetError();
DWORD dwError = m_rapi.CeGetLastError();
return 0;
}
}
catch (CException* e)
{
TCHAR szCause[255];
e->GetErrorMessage(szCause, 255);
CString errorMsg = _T("Error in: CRegEditDoc::AddNewKeyValue: ");
errorMsg += szCause;
AfxMessageBox(errorMsg);
e->Delete();
}
return 1;
}
I would appreciate a little advise on the matter, as this is the first time I have used the RAPI.
Thanks.
Hi VZ800!
The error you're getting is 'access denied'. In WM5 many RAPI functions (including writing to registry) are blocked for security reasons. Your only choice is to use a dll with CeRapiInvoke functions, but it needs to be deployed through a special cab.
You can read about this on msdn.
By the way, the app you're writing already exists, and it has the same problem.
Good luck!
Thanks for the advice. Since my post I have found that my code works for the HKEY_LOCAL_MACHINE, "/Software".
I will investigate the issue you have pointed me to.
Actually, your code should work for the entire HKEY_CLASSES_ROOT as well. MS decided to block only certain 'sensitive' parts of the registry so they can not be corrupted from the outside by malicious software.
If you noticed, MS's own remote registry editor works through DLLs (a ton of them).
Any way, I skimped on words in my first post, since I was writing it on a bus, and while I love my Jamin, writing long text on it is not very enjoyable.
Let me elaborate on CeRapiInvoke:
It's a function you call on the PC side that receives a DLL name and a function name (in that DLL) as parameters and calls that function on the device. It also lets you transfer buffers of data to and from the called function.
It's a great way to communicate with a PPC device without using sockets. You can write the device side DLL to do what ever you wont (like access protected registry) and report back to the PC.
The only drawback is in WM5 this DLL has to be registered and have a 'system' file attribute set. That's why you have to deploy it by cab.
Like I said before it's all in the MSDN.
Hope this helps.
Thanks. I have read the articles (and printed them) about RAPI Restricted Mode Security etc... http://msdn.microsoft.com/library/d...5/html/wce51conRAPIRestrictedModeSecurity.asp and will write a DLL to go on the PPC which will be installed via CAB etc...
I updated the function to add a new value anyway. Rather than calling the RAPI functions for the registry CeRapi... I will call my own functions in my authorised DLL.
Code:
//-----------------------------------------------------------------------------------
// Adds a new key value into the registry.
//
int CRegEditDoc::AddNewKeyValue(HTREEITEM hParent, HKEY hRoot, LPTSTR lpszKey,
LPTSTR lpszValName, DWORD dwDType, LPBYTE lpData)
{
USES_CONVERSION;
HKEY hKey;
LPWSTR lpwszKey = T2W(lpszKey);
LPWSTR lpwszValName = T2W(lpszValName);
DWORD dwDSize = sizeof(lpData);
try
{
if (lstrlen(lpszKey))
{
if (m_rapi.CeRegOpenKeyEx (hRoot, lpwszKey, 0, 0, &hKey) != ERROR_SUCCESS)
{
return 0;
}
}
else
{
hKey = hRoot;
}
// Check if valuename already exists. Should never happen, but just in case.
if (m_rapi.CeRegQueryValueEx(hKey, lpwszValName, 0, &dwDType, NULL, &dwDSize) == ERROR_SUCCESS)
{
AfxMessageBox(_T("Value of this name already exists!"));
return 0;
}
if (m_rapi.CeRegSetValueEx(hKey, lpwszValName, 0, dwDType, lpData, dwDSize) != ERROR_SUCCESS)
{
HRESULT hResult = m_rapi.CeRapiGetError();
DWORD dwError = m_rapi.CeGetLastError();
AfxMessageBox(_T("Unable to create new value for this key!\nPlease check access rights."));
return 0;
}
}
catch (CException* e)
{
TCHAR szCause[255];
e->GetErrorMessage(szCause, 255);
CString errorMsg = _T("Error in: CRegEditDoc::AddNewKeyValue: ");
errorMsg += szCause;
AfxMessageBox(errorMsg);
e->Delete();
}
return 1;
}
A question on using the CeRapiInvoke function. Obviously my function that I will be invoking in my DLL will need to conform to the following footprint:
Code:
LPCWSTR, LPCWSTR, DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream**, DWORD
What I would like to know is this: If I want my function to be a wrapper to say the
Code:
CeRegQueryValueEx(HKEY, LPWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD)
function, how do I parse the function args? Please suggest how I would pack them into a BYTE* for the pInput parameter.
Actually, you got it a bit wrong:
Code:
FuncName(DWORD cbInput, BYTE *pInput, DWORD *pcbOutput, BYTE **ppOutput, IRAPIStream *ppIRAPIStream);
The prototype you specified is for the PC side (the first two strings are DLL name and function name);
I use the following parsing method:
Code:
BYTE* curInputPos = pInput;
memcpy((BYTE*)&hKey, curInputPos, sizeof(HKEY));
curInputPos += sizeof(HKEY);
memcpy((BYTE*)&dwIndex, curInputPos, sizeof(DWORD));
curInputPos += sizeof(DWORD);
memcpy((BYTE*)&Reserved, curInputPos, sizeof(DWORD));
curInputPos += sizeof(DWORD);
It works fine both ways.
Just don't forget to use LocalAlloc for inBuffer and LocalFree for outBuffer.
Thanks. I'll let you know how I get on.
So if I were to parse an HKEY and an LPTSTR accross I would do the following to put the data into a BYTE array:
Code:
DWORD dwIn, dwOut;
LPBYTE pInput;
PDWORD pOut;
dwIn = sizeof(HKEY) + (strlen(lpszKey)*sizeof(TCHAR));
pInput = (BYTE*)(LocalAlloc(LPTR, dwIn));
memcpy(pInput, (BYTE*)&hKey, sizeof(HKEY));
pInput += sizeof(HKEY);
memcpy(pInput, (BYTE*)&lpszKey, strlen(lpszKey)*sizeof(TCHAR));
// move pointer back to begining.
pInput -= sizeof(HKEY);
Basically, yes but with two reservations:
1) I recommend using a different pointer for the current position in buffer, to avoid errors.
2) you need to put the string length in the byte array before the string, otherwise you won't know it's length on the device side. Alternatively, you have to add 1 to the length so the 0 byte at the end gets packed and you can use strlen on the device.
Also keep in mined that unless you define the PC side project to work with UNICODE libraries, THCHAR will be defined as char, while on the device it's always WCHAR.
I really apreciate your help. I still can't get my DLL function to work I keep getting error 1064!
This is my code for the DLL named REditSvr.dll:
Code:
#include <windows.h>
#ifdef __cplusplus
extern "C"
{
#endif
__declspec (dllexport) INT RegEditDeleteValue (DWORD cbInput, BYTE* pInput, DWORD* pcbOutput, BYTE** ppOutput, PVOID reserved);
#ifdef __cplusplus
}
#endif
BOOL WINAPI DllMain (HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
return TRUE;
}
INT RegEditDeleteValue (DWORD cbInput, BYTE* pInput, DWORD* pcbOutput, BYTE** ppOutput, PVOID reserved)
{
INT rc = 0;
BYTE* curInputPos = pInput;
HKEY hKey;
DWORD dwLength;
// Copy args out of input buffer.
memcpy((BYTE*)&hKey, curInputPos, sizeof(HKEY));
curInputPos += sizeof(HKEY);
memcpy((BYTE*)&dwLength, curInputPos, sizeof(DWORD));
curInputPos += sizeof(DWORD);
// Allocate enough memory for local wchar.
LPWSTR lpszValueName = (WCHAR*)malloc(dwLength);
memcpy((BYTE*)&lpszValueName, curInputPos, sizeof(dwLength));
curInputPos += sizeof(dwLength);
// Do the registry delete.
rc = RegDeleteValue(hKey, lpszValueName);
// Allocate memory for the return buffer.
BYTE* pOutput = (BYTE*)LocalAlloc(LPTR, sizeof(long));
memcpy(pOutput, (BYTE*)rc, sizeof(long));
*ppOutput = pOutput;
*pcbOutput = sizeof(long);
// Free input buffer.
LocalFree(pInput);
// Free WCHAR
free(lpszValueName);
return GetLastError();
}
and this is the code in my PC application which invokes the above function (or I would hope it did):
Code:
//-----------------------------------------------------------------------------------
// Deletes the key value from the registry.
//
int CRegEditDoc::DeleteKeyValue(HKEY hRoot, LPCTSTR lpszKey, LPCTSTR lpszValName)
{
USES_CONVERSION;
HKEY hKey;
LPWSTR lpwszKey = T2W(lpszKey);
LPWSTR lpwszValName = T2W(lpszValName);
try
{
if (lstrlen(lpszKey))
{
if (m_rapi.CeRegOpenKeyEx (hRoot, lpwszKey, 0, 0, &hKey) != ERROR_SUCCESS)
{
return 0;
}
}
else
{
hKey = hRoot;
}
/* if (m_rapi.CeRegDeleteValue(hKey, lpwszValName) != ERROR_SUCCESS)
{
HRESULT hResult = m_rapi.CeRapiGetError();
DWORD dwError = m_rapi.CeGetLastError();
AfxMessageBox(_T("Unable to delete value for this key!\nPlease check access rights."));
return 0;
}
*/
// Testing remote registry value deletion.
DWORD dwIn, dwOut;
LPBYTE pInput, pCurInputPos;
PDWORD pOut;
DWORD dwLength = wcslen(lpwszValName)*sizeof(WCHAR);
dwIn = sizeof(HKEY) + dwLength;
pInput = (BYTE*)(LocalAlloc(LPTR, dwIn));
pCurInputPos = pInput;
memcpy(pCurInputPos, (BYTE*)&hKey, sizeof(HKEY));
pCurInputPos += sizeof(HKEY);
// Store the length of the string
memcpy(pCurInputPos, (BYTE*)&dwLength, sizeof(DWORD));
pCurInputPos += sizeof(DWORD);
memcpy(pCurInputPos, (BYTE*)&lpwszValName, dwLength);
HRESULT hr = m_rapi.CeRapiInvoke(L"REditSvr", L"RegEditDeleteValue", dwIn,
pInput, &dwOut, (PBYTE*)&pOut, NULL, 0);
HRESULT hResult = m_rapi.CeRapiGetError();
DWORD dwError = m_rapi.CeGetLastError();
LocalFree(pOut);
if (hKey != hRoot)
{
m_rapi.CeRegCloseKey(hKey);
}
}
catch (CException* e)
{
TCHAR szCause[255];
e->GetErrorMessage(szCause, 255);
CString errorMsg = _T("Error in: CRegEditDoc::DeleteKeyValue: ");
errorMsg += szCause;
AfxMessageBox(errorMsg);
e->Delete();
}
return 1;
}
The DLL has been deployed to the PPC \Windows folder by eVC4. My PPC runs WM5 (is this the problem, although I have written programs with eVC4 ok for it).
I would again appreciate your help/advice on why this isn't working. At present I have unlocked my PPC and I am able to edit any part of the registry etc...
Hi VZ800!
I noticed a couple of errors in your code (which you may have corrected yourself by now) but the biggest problem, I think is that you don't register the dll.
Here is the part you missed from MSDN:
(full link: http://msdn.microsoft.com/library/d...en-us/mobilesdk5/html/mob5lrfcerapiinvoke.asp)
To satisfy the requirements of the Remote Access Security Policy
1. Create a provisioning XML document that adds the new node "RAPI" to the metabase. This node must include the absolute path to the *.DLL file. For more information, see Metabase Settings. The following code example shows the contents of a typical provisioning XML file.
<wap-provisioningdoc>
<characteristic type="Metabase">
<characteristic type="RAPI\Program Files\Green Sky\recaller.dll\*">
<parm name="rw-access" value="3"/>
<parm name="access-role" value="152"/>
</characteristic>
</characteristic>
</wap-provisioningdoc>
2. Pass the file name of the provisioning XML document to the CAB wizard using the /postxml command line option. The CAB wizard will append the XML to the _setup.xml file it places in the CAB. For more information on creating CAB files, see CAB Wizard.
3. Set the System attribute on the *.DLL file.
Only the Manager security role provides the required permissions for modifying the metabase. The ideal way to get this security role is to have your application signed with a privileged certificate.
Note Since Pocket PC implements a one-tier security model, the CAB install process will automatically have the Manager security role.
Click to expand...
Click to collapse
Here's my advice:
Create a simple function that doesn't receive parameters, but pops up a message on the device. When you see that calling it works, try adding the rest of the code.
Hi
As I understand the DLL does not require code to self- register. Anyway, I can call the DLL function and did as you suggested and put a MessageBox in the function. This displayed fine. My code for the DLL is as follows now:
Code:
#include <windows.h>
#ifdef __cplusplus
extern "C"
{
#endif
__declspec (dllexport) INT RegEditDeleteValue (DWORD cbInput, BYTE* pInput, DWORD* pcbOutput, BYTE** ppOutput, PVOID reserved);
#ifdef __cplusplus
}
#endif
BOOL WINAPI DllMain (HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
return TRUE;
}
INT RegEditDeleteValue (DWORD cbInput, BYTE* pInput, DWORD* pcbOutput, BYTE** ppOutput, PVOID reserved)
{
DWORD rc = 0;
BYTE* curInputPos = pInput;
LPCWSTR lpszValueName;
HKEY hKey;
int len;
// Copy args out of input buffer.
memcpy((BYTE*)&hKey, curInputPos, sizeof(HKEY));
curInputPos += sizeof(HKEY);
// Size of value name string.
memcpy((BYTE*)&len, curInputPos, sizeof(int));
curInputPos += sizeof(int);
// Value name string.
memcpy((BYTE*)&lpszValueName, curInputPos, sizeof(len));
curInputPos += sizeof(len);
// Do the registry delete.
rc = RegDeleteValue(hKey, lpszValueName);
// Allocate memory for the return buffer.
*ppOutput = (BYTE*)LocalAlloc(LPTR, rc);
memcpy(*ppOutput, (BYTE*)&rc, sizeof(DWORD));
*pcbOutput = sizeof(DWORD);
// Free input buffer.
if (pInput)
LocalFree(pInput);
return GetLastError();
}
and this is the code from which I am calling it:
Code:
//-----------------------------------------------------------------------------------
// Deletes the key value from the registry.
//
int CRegEditDoc::DeleteKeyValue(HKEY hRoot, LPCTSTR lpszKey, LPCTSTR lpszValName)
{
USES_CONVERSION;
HKEY hKey;
LPWSTR lpwszKey = T2W(lpszKey);
LPCWSTR lpwszValName = T2W(lpszValName);
try
{
if (lstrlen(lpszKey))
{
if (m_rapi.CeRegOpenKeyEx (hRoot, lpwszKey, 0, 0, &hKey) != ERROR_SUCCESS)
{
return 0;
}
}
else
{
hKey = hRoot;
}
/* if (m_rapi.CeRegDeleteValue(hKey, lpwszValName) != ERROR_SUCCESS)
{
HRESULT hResult = m_rapi.CeRapiGetError();
DWORD dwError = m_rapi.CeGetLastError();
AfxMessageBox(_T("Unable to delete value for this key!\nPlease check access rights."));
return 0;
}
*/
// Testing remote registry value deletion.
DWORD dwIn, dwOut;
LPBYTE pInput, pCurInputPos;
PDWORD pOut, rc;
int len = wcslen(lpwszValName)*sizeof(WCHAR);
dwIn = sizeof(HKEY) + len;
pInput = (BYTE*)(LocalAlloc(LPTR, dwIn));
pCurInputPos = pInput;
// Store the hKey value in the output buffer.
memcpy(pCurInputPos, (BYTE*)&hKey, sizeof(HKEY));
pCurInputPos += sizeof(HKEY);
// Store the length of the string in the output buffer.
memcpy(pCurInputPos, (BYTE*)&len, sizeof(int));
pCurInputPos += sizeof(int);
// Store the value name string in the output buffer.
memcpy(pCurInputPos, (BYTE*)&lpwszValName, len);
HRESULT hr = m_rapi.CeRapiInvoke(L"REditSvr", L"RegEditDeleteValue", dwIn,
pInput, &dwOut, (PBYTE*)&pOut, NULL, 0);
// HRESULT hr = RapiFuncTest(dwIn, pInput, &dwOut, (PBYTE*)&pOut, NULL);
HRESULT hResult = m_rapi.CeRapiGetError();
DWORD dwError = m_rapi.CeGetLastError();
if (dwOut)
{
memcpy((BYTE*)&rc, pOut, sizeof(DWORD));
}
if (pOut)
{
LocalFree(pOut);
}
if (hKey != hRoot)
{
m_rapi.CeRegCloseKey(hKey);
}
}
catch (CException* e)
{
TCHAR szCause[255];
e->GetErrorMessage(szCause, 255);
CString errorMsg = _T("Error in: CRegEditDoc::DeleteKeyValue: ");
errorMsg += szCause;
AfxMessageBox(errorMsg);
e->Delete();
}
return 1;
}
As you can see in the DeleteKeyValue(...) function I called a test-function just to check that I was retrieving the data out of the pInput buffer ok, which I am.
I signed the DLL with the SDKSamplePrivDeveloper.pfx, added the /postxml via the /postxml switch in the cabwiz and successfully created a CAB file which installs the DLL into the \Windows folder on the PPC. The .inf file is as follows:
Code:
[CEStrings]
InstallDir=%CE2%
AppName="REditSvr"
[Strings]
CompanyName="AHartley"
[Version]
Signature="$Chicago$"
CESignature="$Windows CE$"
Provider=%CompanyName%
[SourceDisksNames.Arm]
1=,"arm files",,C:\eMDevelopment\PPCRegEdit\REditSvr\REL
[SourceDisksFiles.Arm]
REditSvr.dll=1
[Files.ARM]
REditSvr.dll
[DestinationDirs]
Files.Arm=,%InstallDir%
[DefaultInstall.Arm]
CopyFiles=Files.Arm
My PC side code invokes the DLL function return 0 as error code. But the error code returned in the ppOutput buffer is 0x00000057 Dec 87. Which equates to the error message "The parameter is incorrect."! Which must be a param of the RegDeleteValue(...) function, as if I comment this out I don't get any error return values!!
Any odeas?
This is all academic now as I won't be finishing the PPCRegEdit program coz of the Remote Registry Editor tool available in the eVC4 IDE, which I hadn't noticed before, duh. But I would like to know why the function isn't working as required.
You were writing this as a tool? :shock:
If you just asked, people would have told you about the existing reg edit and CeRegEdit witch works through RAPI directly.
Still, it is a nice exercise in coding which I done my self once (for other purposes)
Any way, your error is simple:
Code:
// Value name string.
memcpy((BYTE*)&lpszValueName, curInputPos, sizeof(len));
curInputPos += sizeof(len);
You are parsing it incorrectly.
This is how it should look:
Code:
// Value name string.
memcpy((BYTE*)lpszValueName, curInputPos, len);
curInputPos += len;
and on the PC side:
Code:
memcpy(pCurInputPos, (BYTE*)&lpwszValName, len);
should be:
Code:
memcpy(pCurInputPos, (BYTE*)lpwszValName, len);
once again, no offence but if you just read your code more carefully and use debug prints to check parameters, you won't need anyone's help.
Good luck in future projects.
(whoops, made an error my self while correcting another)
Yes, it is just an exercise.
Thanks for all your help. Sorry for the silly errors, I will try and take more care in future.

Get notified when process is started

I want to know if there is a way to get notified from windows pocket pc
system when a process is started or a new window is created.
Is there an API call that will manage this?
Thanks.
Houser
Houser said:
I want to know if there is a way to get notified from windows pocket pc
system when a process is started or a new window is created.
Is there an API call that will manage this?
Thanks.
Houser
Click to expand...
Click to collapse
Nope.
The only thing available is using the toolhelp library, by getting the current process list and update it, you can determine if a process started or stopped.
For the windows, it's the same, there isn't any notification mechanism to do that.
Cheers,
.Fred
On the BB Windows, you can install a system-wide hook and catch WM_CREATE notifications. Probably there is something similar for Mobile...
Lurker0 said:
On the BB Windows, you can install a system-wide hook and catch WM_CREATE notifications. Probably there is something similar for Mobile...
Click to expand...
Click to collapse
In coredll.dll, the SetWindowsHookEx function is defined but is undocumented. Maybe the declaration is the same that the one under Windows, you can have try.
I found in PB5 header pwinuser.h the following declarations:
Code:
typedef LRESULT (CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);
HHOOK
WINAPI
SetWindowsHookExW(
int idHook,
HOOKPROC lpfn,
HINSTANCE hmod,
DWORD dwThreadId);
#define SetWindowsHookEx SetWindowsHookExW
BOOL
WINAPI
UnhookWindowsHookEx(
HHOOK hhk);
LRESULT
WINAPI
CallNextHookEx(
HHOOK hhk,
int nCode,
WPARAM wParam,
LPARAM lParam);
Cheers,
.Fred
dotfred said:
In coredll.dll, the SetWindowsHookEx function is defined but is undocumented. Maybe the declaration is the same that the one under Windows, you can have try.
I found in PB5 header pwinuser.h the following declarations:
Code:
typedef LRESULT (CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);
HHOOK
WINAPI
SetWindowsHookExW(
int idHook,
HOOKPROC lpfn,
HINSTANCE hmod,
DWORD dwThreadId);
#define SetWindowsHookEx SetWindowsHookExW
BOOL
WINAPI
UnhookWindowsHookEx(
HHOOK hhk);
LRESULT
WINAPI
CallNextHookEx(
HHOOK hhk,
int nCode,
WPARAM wParam,
LPARAM lParam);
Cheers,
.Fred
Click to expand...
Click to collapse
The idHook you're interested in is WH_CBT and it seems to work in WINCE5.
Cheers,
.Fred
Hey that sounds good. Thanks so far.
I will try this now with SetWindowsHookExW().
Currently I am polling the process list with toolhelp library.
But this is not so good for performance and battery.
Houser
So I have tried this and have written a Dll where I hook
the WH_CBT with SetWindowsHookExW.
I have loaded the function pointers from the coredll.dll with LoadLibrary()
which is ok. But when I call SetWindowsHookExW() in my hook Dll
theh I get always error 87 back.
This is my code in the hook dll to install the hook.
Any ideas what is wrong here?
Code:
BOOL __declspec(dllexport)__stdcall InstallHook()
{
log(( TEXT("InstallHook") ));
g_hDll = LoadLibrary( TEXT("\\windows\\coredll.dll") );
if( g_hDll == NULL )
{
err(( TEXT("LoadLibrary") ));
return FALSE;
}
fpSetWindowHookEx = (SETWINDOWHOOKEX) GetProcAddress( g_hDll, TEXT("SetWindowsHookExW") );
if( fpSetWindowHookEx == NULL )
{
MessageBox( NULL, TEXT("SetWindowsHookExW"), TEXT(""), MB_OK );
}
fpUnhook = (UNHOOKWINDOWHOOKEX) GetProcAddress( g_hDll, TEXT("UnhookWindowsHookEx") );
if( fpUnhook == NULL )
{
MessageBox( NULL, TEXT("UnhookWindowsHookEx"), TEXT(""), MB_OK );
}
fpCallNextHook = (CALLNEXTHOOKEX) GetProcAddress( g_hDll, TEXT("CallNextHookEx") );
if( fpCallNextHook == NULL )
{
MessageBox( NULL, TEXT("CallNextHookEx"), TEXT(""), MB_OK );
}
g_hHook = fpSetWindowHookEx( WH_CBT, (HOOKPROC) CBTProc, g_hInstanceDll, 0 );
if( g_hHook == NULL )
{
err(( TEXT("fpSetWindowHookEx failed <%d>!"), GetLastError() ));
MessageBox( NULL, TEXT("fpSetWindowHookEx failed!"), TEXT(""), MB_OK );
return FALSE;
}
return TRUE;
}
Houser said:
So I have tried this and have written a Dll where I hook
the WH_CBT with SetWindowsHookExW.
I have loaded the function pointers from the coredll.dll with LoadLibrary()
which is ok. But when I call SetWindowsHookExW() in my hook Dll
theh I get always error 87 back.
This is my code in the hook dll to install the hook.
Any ideas what is wrong here?
Code:
BOOL __declspec(dllexport)__stdcall InstallHook()
{
log(( TEXT("InstallHook") ));
g_hDll = LoadLibrary( TEXT("\\windows\\coredll.dll") );
if( g_hDll == NULL )
{
err(( TEXT("LoadLibrary") ));
return FALSE;
}
fpSetWindowHookEx = (SETWINDOWHOOKEX) GetProcAddress( g_hDll, TEXT("SetWindowsHookExW") );
if( fpSetWindowHookEx == NULL )
{
MessageBox( NULL, TEXT("SetWindowsHookExW"), TEXT(""), MB_OK );
}
fpUnhook = (UNHOOKWINDOWHOOKEX) GetProcAddress( g_hDll, TEXT("UnhookWindowsHookEx") );
if( fpUnhook == NULL )
{
MessageBox( NULL, TEXT("UnhookWindowsHookEx"), TEXT(""), MB_OK );
}
fpCallNextHook = (CALLNEXTHOOKEX) GetProcAddress( g_hDll, TEXT("CallNextHookEx") );
if( fpCallNextHook == NULL )
{
MessageBox( NULL, TEXT("CallNextHookEx"), TEXT(""), MB_OK );
}
g_hHook = fpSetWindowHookEx( WH_CBT, (HOOKPROC) CBTProc, g_hInstanceDll, 0 );
if( g_hHook == NULL )
{
err(( TEXT("fpSetWindowHookEx failed <%d>!"), GetLastError() ));
MessageBox( NULL, TEXT("fpSetWindowHookEx failed!"), TEXT(""), MB_OK );
return FALSE;
}
return TRUE;
}
Click to expand...
Click to collapse
87 means invalid parameter:
I think I know why!
Here read this:
hMod
[in] Handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
dwThreadId
[in] Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop as the calling thread.
So I would change your call by this one:
Code:
g_hHook = fpSetWindowHookEx( WH_CBT, (HOOKPROC) CBTProc, NULL, ::GetCurrentThreadId() );
or
Code:
g_hHook = fpSetWindowHookEx( WH_CBT, (HOOKPROC) CBTProc, NULL, 0 );
Cheers,
.Fred
I have tries both suggestions from you, but always error 87.
Have tried this in a dll and in an exe but same error.
Here is my callback function code:
Code:
LRESULT __declspec(dllexport)__stdcall CALLBACK CBTProc( int nCode, WPARAM wParam, LPARAM lParam )
{
if( nCode == HCBT_CREATEWND )
{
log(( TEXT("----> Window created") ));
}
LRESULT RetVal = fpCallNextHook( g_hHook, nCode, wParam, lParam );
return RetVal;
}
Houser
Houser said:
I have tries both suggestions from you, but always error 87.
Have tried this in a dll and in an exe but same error.
Here is my callback function code:
Code:
LRESULT __declspec(dllexport)__stdcall CALLBACK CBTProc( int nCode, WPARAM wParam, LPARAM lParam )
{
if( nCode == HCBT_CREATEWND )
{
log(( TEXT("----> Window created") ));
}
LRESULT RetVal = fpCallNextHook( g_hHook, nCode, wParam, lParam );
return RetVal;
}
Houser
Click to expand...
Click to collapse
Why are you exporting the CALLBACK function ?
Thanks for your quick answers.
Hmm I have seen this in a desktop sample hook dll project
and have copied this.
Tried the dll without exporting the callback function but same error.
I am really confused what param is invalid.
Have defined this in my dll:
Code:
typedef LRESULT (CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);
#define WH_CBT 5
I think this is correct.
Have you ever calles SetWindowsHookExW() successfully on pocket pc?
Houser
Houser said:
Thanks for your quick answers.
Hmm I have seen this in a desktop sample hook dll project
and have copied this.
Tried the dll without exporting the callback function but same error.
I am really confused what param is invalid.
Have defined this in my dll:
Code:
typedef LRESULT (CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);
#define WH_CBT 5
I think this is correct.
Have you ever calles SetWindowsHookExW() successfully on pocket pc?
Houser
Click to expand...
Click to collapse
I didn't try yet. Let me test! Give some feedback in a few minutes...
Got it now.
The problem was the first param WH_CBT (5) which is not supported.
Have now taken 20 for a try and it works.
The question is now is WH_CBT not supported or is 5 the wrong ID.
I will check this in PB header files.
Houser
dotfred said:
I didn't try yet. Let me test! Give some feedback in a few minutes...
Click to expand...
Click to collapse
Well it doesn't work, and I took the declarations from PB5.
So my guess is it simply doesn't work under WM5. Because it works under WCE5.
I think a little bit of disassembling is required here!
Cheers,
.Fred
So you have tried it with Hook ID 5 under CE5 and NOT under
WM5 (Pocket PC)?
And under CE5 it works? :-(
I have get it with Hook ID 20 and the function call was ok.
Houser
Houser said:
So you have tried it with Hook ID 5 under CE5 and NOT under
WM5 (Pocket PC)?
And under CE5 it works? :-(
I have get it with Hook ID 20 and the function call was ok.
Houser
Click to expand...
Click to collapse
In fact, the only one I tested under WM5 is WH_KEYBOARD_LL (20) as you did!
I never tried the others because I never needed it!
And I never tested it under WINCE5 but I found some code of MFC controls classes implementation under PB5 like the CCommandBarCtrl that use the WH_CBT.

iTask development need help with dll files

Hi! I'm pretty stuck with developing more useful things for iTask so I'm entering the dark and dangerous world of c++.
I don't know anything about eMbedded VisualC++, so I hope someone here can help me get some more information out of the ppc, like free memory, storage, signal, etc, if it is easy and possible.
The flash command to read this is "GetPowerStatus". So that must be changed to something new in the script.
Hopeful for any answer!
This is the sample file that comes with bryht flashapp for importing battery percent info. It works.
if you need the evc files as well please post.
Here's the script:
#include "stdafx.h"
#include "plugin.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
const char *g_command[] = {
"GetPowerStatus",
NULL,
};
SETVARIABLE SetVariable = NULL;
FLASHAPPPLUGIN_API const char** WINAPI RegisterCommand(SETVARIABLE pSetVariable)
{
SetVariable = pSetVariable;
return g_command;
}
FLASHAPPPLUGIN_API int DoCommand(HWND hWnd, const char*cmd, const char*params, int argc, char* argv[])
{
if( _stricmp( cmd, "GetPowerStatus" ) == 0 )
{
#ifdef _WIN32_WCE
SYSTEM_POWER_STATUS_EX sp;
memset( &sp, 0, sizeof(sp));
GetSystemPowerStatusEx( &sp, TRUE );
#else //for windows desktop version
SYSTEM_POWER_STATUS sp;
memset( &sp, 0, sizeof(sp));
GetSystemPowerStatus( &sp, TRUE );
#endif
//send the value to Flash
char value[32];
sprintf( value, "%d", sp.BackupBatteryLifePercent );
if( argc>0 && argv[0]!= 0 )
SetVariable( argv[0], value );
}
return FLASHAPP_OK;
}

problem with injection DLL to specified process

Save me from madness!!!
I have a several smartphone devices with windows CE
CE 6.0 - hp IPAQ 500 series
CE 5.0 - Samsung i600
I need to inject DLL into the process "home.exe". I use method with performcallback4 function. This method works successfully for all processes ("device.exe", "service.exe", etc.) except process "home.exe". In what a problem?
source code : InjectDLL.exe link with toolhelp.lib
#include <windows.h>
#include <Tlhelp32.h>
typedef struct _CALLBACKINFO {
HANDLE hProc;
FARPROC pfn;
PVOID pvArg0;
} CALLBACKINFO;
extern "C"
{
DWORD PerformCallBack4(CALLBACKINFO *pcbi,...);
LPVOID MapPtrToProcess(LPVOID lpv, HANDLE hProc);
BOOL SetKMode(BOOL fMode);
DWORD SetProcPermissions(DWORD newperms);
};
DWORD GetProcessId(WCHAR *wszProcessName)
{
HANDLE hTH= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe;
pe.dwSize= sizeof(PROCESSENTRY32);
DWORD PID=0;
if (Process32First(hTH, &pe))
{
do {
if (wcsicmp(wszProcessName, pe.szExeFile)==0)
{
PID=pe.th32ProcessID;
}
} while (Process32Next(hTH, &pe));
}
CloseToolhelp32Snapshot(hTH);
return PID;
}
HMODULE GetDllHandle(DWORD ProcessId,WCHAR* ModuleName)
{
HANDLE ToolHelp=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,ProcessId);
if (ToolHelp!=INVALID_HANDLE_VALUE)
{
MODULEENTRY32 ModuleEntry={sizeof MODULEENTRY32};
if (Module32First(ToolHelp,&ModuleEntry))
do
{
if (wcsicmp(ModuleEntry.szModule, ModuleName)==0)
return ModuleEntry.hModule;
}
while(Module32Next(ToolHelp,&ModuleEntry));
CloseToolhelp32Snapshot(ToolHelp);
}
return NULL;
}
BOOL InjectDll(WCHAR* ProcessName,WCHAR* ModuleName)
{
DWORD ProcessId=GetProcessId(ProcessName);
HMODULE ModuleHandle=GetDllHandle(ProcessId,ModuleName);
if (ModuleHandle!=NULL)
return TRUE;
HANDLE Process=OpenProcess(0,0,ProcessId);
if (Process==NULL)
return FALSE;
void* ModuleNamePtr=MapPtrToProcess(ModuleName,GetCurrentProcess());
if (ModuleNamePtr==NULL)
return FALSE;
CALLBACKINFO ci;
ci.hProc=Process;
void* LoadLibraryPtr=MapPtrToProcess(GetProcAddress(GetModuleHandle(L"coredll.dll"),L"LoadLibraryW"),Process);
if (LoadLibraryPtr==NULL)
return FALSE;
ci.pfn=(FARPROC)LoadLibraryPtr;
ci.pvArg0=ModuleNamePtr;
PerformCallBack4(&ci); in this place process exit. visual studio output message : "process exit with code 0xc0000030"
Sleep(500);
CloseHandle(Process);
return GetDllHandle(ProcessId,ModuleName)!=NULL;
}
extern "C"
{
BOOL SetKMode(BOOL fMode);
DWORD SetProcPermissions(DWORD newperms);
};
#define DLLNAME L"MyDll.dll"
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR lpCmdLine,int nShowCmd)
{
WCHAR Path[MAX_PATH];
GetModuleFileName(NULL,Path,MAX_PATH);
wcscpy(wcsrchr(Path,L'\\')+1,DLLNAME);
WCHAR NewPath[MAX_PATH]=L"\\Windows\\";
wcscat(NewPath,DLLNAME);
CopyFile(Path,NewPath,FALSE);
BOOL Res=InjectDll(L"home.exe",L"MyDll.dll");
return 0;
}
the error code is
#define STATUS_INVALID_PARAMETER_MIX 0xC0000030
(maybe too fast for getting the thread infos?)
try to make the "Sleep(500);" before "PerformCallBack4(&ci);"
I have tried, a problem not in it. Any ideas?
I have not found the reason.... I Use other method without performcallback4
Problem with injection dll to cprog.exe process?
I want to inject dll to cprog.exe process. but it doesn't work.
source code.
Code:
VOID
InjectDllToCprog()
{
WCHAR DllPath[MAX_PATH] = L"";
CallbackInfo ci;
GetModuleFileName(NULL, DllPath, MAX_PATH);
PWCHAR p = wcsrchr(DllPath, L'\\');
DllPath[p - DllPath] = '\0';
wcscat(DllPath, L"\\CprogInject.dll");
ZeroMemory(&ci, sizeof(ci));
g_hCprog = FindCprogProcess(L"Cprog.exe"); // the handle is right.
if(g_hCprog != NULL)
{
DWORD dwMode = SetKMode(TRUE);
DWORD dwPerm = SetProcPermissions(0xFFFFFFFF);
FARPROC pFunc = GetProcAddress(GetModuleHandle(L"Coredll.dll"), L"LoadLibraryW");
ci.ProcId = (HANDLE)g_hCprog;
ci.pFunc = (FARPROC)MapPtrToProcess(pFunc, g_hCprog);
ci.pvArg0 = MapPtrToProcess(DllPath, GetCurrentProcess());
g_InjectCprog = (HINSTANCE)PerformCallBack4(&ci, 0, 0, 0);
if(GetLastError() != 0) // GetLastError() = 5
DbgError(L"PerformCallBack 执行失败", GetLastError());
SetKMode(dwMode);
SetProcPermissions(dwPerm);
}
}
GetLastError() return 0x00000005(Access is denied)
Anyone can help me? Sorry for my poor english.

Porting / Converting Windows .exe to Windows Mobile .cab/exe

Ive looked but havnt managed to find a windows .exe convertor to windows mobile. Ive found a program which can shutdown remote pcs on the same network and want to port it to my windows mobile (6.1) - HTC Kaiser.
Ive installed the visual studio and the sdk aswell as the 2.0 mobile framework.
Any ideas where to go from here?
Thanks
Source code to Windows App...
Code:
//-----------------------------------------------------------
// Remote Shutdown v1.0 Console Mode
// Copyright (C) 2002, MATCODE Software
// http://www.matcode.com
// Author: Vitaly Evseenko
//-----------------------------------------------------------
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#pragma hdrstop
int RemoteShutdown(LPSTR lpMachineName, LPSTR lpMessage,
DWORD dwTimeout, BOOL bForceAppsClosed,
BOOL bRebootAfterShutdown )
{
HANDLE hToken;
TOKEN_PRIVILEGES TokenPrivileges;
OpenProcessToken( GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) ;
LookupPrivilegeValue( NULL, SE_REMOTE_SHUTDOWN_NAME, &(TokenPrivileges.Privileges[0].Luid));
TokenPrivileges.PrivilegeCount = 1;
TokenPrivileges.Privileges[0].Attributes = 2;
AdjustTokenPrivileges( hToken, FALSE, &TokenPrivileges,
sizeof(TOKEN_PRIVILEGES), NULL, NULL );
if(!InitiateSystemShutdown(
lpMachineName, // name of computer to shut down
lpMessage, // address of message to display
dwTimeout, // time to display dialog box
bForceAppsClosed, // force applications with unsaved changes flag
bRebootAfterShutdown ))
{
return GetLastError();
}
return 0;
}
void OutUsage(void)
{
printf("\nUsage: RSD-CON ComputerName [Message] [/tnn] [/f] [/s]\n");
printf("\tComputerName - remote computer name\n");
printf("\tMessage - specify message to display\n");
printf("\t/t - time to display message (nn seconds)\n");
printf("\t/f - do not force applications with unsaved changes flag\n");
printf("\t/s - the computer is to shut down.\n");
printf("Example: RSD-CON PC_LARRY This computer will be restarted now. /t20\n");
}
void main( int argc, char *argv[] )
{
char szMachineName[100];
char szMessage[200];
DWORD dwTimeout;
BOOL bForceAppsClosed;
BOOL bRebootAfterShutdown;
int i, Err;
printf("Remote Shutdown v1.0, Console\n");
printf("Copyright (C) 2002, MATCODE Software\n");
printf("http://www.matcode.com\n");
if (GetVersion() & 0x80000000) // Not Windows NT/2000/XP
{
printf("\n\tThis is a Windows NT/2000/XP application.\n"
"This program will not work on Windows 95/98/ME !\n");
return;
}
if(argc<2)
{
OutUsage();
return;
}
strcpy(szMachineName, argv[1]);
dwTimeout = 0;
bForceAppsClosed = TRUE;
bRebootAfterShutdown = TRUE;
szMessage[0] = '\0';
for( i = 2; i < argc; i++ )
{
// if not started with / then message ;-)
if( argv[i][0] != '/')
{
strcat(szMessage, argv[i]);
strcat(szMessage, " ");
continue;
}
// parse option type
if(argv[i][1]=='t' || argv[i][1]=='T')
{
dwTimeout = atol(&argv[i][2]);
}
else if(argv[i][1]=='f' || argv[i][1]=='F')
{
bForceAppsClosed = FALSE;
}
else if(argv[i][1]=='s' || argv[i][1]=='S')
{
bRebootAfterShutdown = FALSE;
}
}
if (dwTimeout == 0 && szMessage[0])
{
dwTimeout = 5;
}
Err = RemoteShutdown(szMachineName, szMessage,
dwTimeout, bForceAppsClosed,
bRebootAfterShutdown );
if(Err)
{
LPSTR lpstErr = "\0";
if(Err == 53)
{
lpstErr = "The network path was not found.\n"
"Invalid computer name or is not Windows NT/2000/XP machine.\n";
}
else if(Err == 5)
{
lpstErr = "Access is denied. You have no administrative rights on the specified computer.\n";
}
printf("\nUnable to shutdown computer %s, Error: %d.\n%s",
szMachineName, Err, lpstErr);
OutUsage();
}
else
{
printf("\nComputer %s is shut down.\n", szMachineName);
}
}
Hi
This is not that easy. While a lot API calls exists in both Windows and WinMo I doubt that the ones used in this tool are available.
cool this is one development many people is waiting for, especially me
wish you good luck
Hi..interesting topics anyway.
As long as the APIs used in Windows app are also available in Windows Mobile, that will be possible IMO.
The one I'm sure about, the Windows Mobile apps built using .net, will also be available to run in Windows

Categories

Resources