I have a background service DLL running on Windows Mobile 2003 in Services.exe.
I now wish to port it to run in Devices.exe. I have so far been unable to get it to run. Instead when I run the ActivateDevice or ActivateDeviceEx it returns with error 1,2 or 120.
What is required by my DLL to be compatable with Devices.exe?
I have added what I assume are the correct registry settings under HKLM\\Devices\\Name so i can only assume it is something wrong with the DLL itself.
If anyone can assist me with this problem it would be greatly appreciated.
Cheers Gerard
Do I need to use the Developer Platform to create the driver or is Embedded fine?
You can use eVC to create drivers.
To make your driver recognized by OS you should add registry keys:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\_name_]
"Prefix"="BLA" - 3 CAPS letters, it is your driver prefix
"Index"=dword:00000001
"Dll"="yourdriver.Dll"
And your driver should export functions:
BLA_Close
BLA_Deinit
BLA_IOControl
BLA_Init
BLA_Open
BLA_PowerDown
BLA_PowerUp
BLA_Read
BLA_Seek
BLA_Write
Later you can use CreateFile(L"BLA1:",...) to communicate with your driver. Read MSDN for more.
I have those entries in the registry and my DLL exports those functions.
However, I can not get the DLL to start through ActivateDeviceEx or ActivateDevice. If I reset the device the device freezes and requires a hard reset.
My DLL works fine in Services.exe but must need some changes to operate in Device.exe. The problem being that I can't find any examples where a Device Driver was written in C++ (all .c) and also can't find any examples of a Service being converted to a Device driver.
Any suggestions greatly appreciated
You don't need to call ActivateDexice[Ex] if you have manually added these keys to registry. The reason that your device hangs is in your DLL's entry point or in one of the exported functions. Probably BLA_Init or one of the power functions. You should add diagnostics code that outputs a trace log to SD-card or built-in storage so that you can read this file after hard reset. Or the reason may be that your driver is loaded before the one of the needed drivers, for example SD-card. In this case you should play with the "order" key.
I've wrote several drivers in C++. But none of them used C++ exceptions, I don't know how devices.exe would behave if exception is thrown. And you should remember not to allocate huge arrays/variables on stack.
I've found a small tutorial on MSDN - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnembedded/html/spotwincerambl.asp
Posted: Wed Mar 09, 2005 18:19
--------------------------------------------------------------------------------
So if I already have the registry entries in do I start the DLL with CreateFile or something similar? I assumed that the DLL was hanging on device startup due to attempting to include an unloaded module but this still occurs when setting Order to 99.
At the moment for testing purposes I am just getting all my exported functions to write to a log file... however none are ever entered. What is the DLL's entry point? Init? PowerUp? An additional method? Have you an example that I could possibly have a look at?
Thanks for your help.
Gerard
The first entry point is DllMain. Then init function is called. Then open when your device is opened. If you have global classes with constructors - constructors are called before DllMain (I have not tested that), one of them may be the reason of crash.
The sample is in the link I gave in the prev. post. or here is a sample driver that is a wrapper around Serial_BTUR.dll
Code:
// Serial.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "Serial.h"
#include <psapi.h>
#include <Mmsystem.h>
struct HCI_
{
char *Text;
int Code;
} Cmds[]=
{
"HCI_NOP",0x0000,
"HCI_Inquiry",0x0401,
"HCI_Inquiry_Cancel",0x0402,
"HCI_Periodic_Inquiry_Mode",0x0403,
"HCI_Exit_Periodic_Inquiry_Mode",0x0404,
"HCI_Create_Connection",0x0405,
"HCI_Disconnect",0x0406,
"HCI_Add_SCO_Connection",0x0407,
"HCI_Accept_Connection_Request",0x0409,
"HCI_Reject_Connection_Request",0x040a,
"HCI_Link_Key_Request_Reply",0x040b,
"HCI_Link_Key_Request_Negative_Reply",0x040c,
"HCI_PIN_Code_Request_Reply",0x040d,
"HCI_PIN_Code_Request_Negative_Reply",0x040e,
"HCI_Change_Connection_Packet_Type",0x040f,
"HCI_Authentication_Requested",0x0411,
"HCI_Set_Connection_Encryption",0x0413,
"HCI_Change_Connection_Link_Key",0x0415,
"HCI_Master_Link_Key",0x0417,
"HCI_Remote_Name_Request",0x0419,
"HCI_Read_Remote_Supported_Features",0x041b,
"HCI_Read_Remote_Version_Information",0x041d,
"HCI_Read_Clock_Offset",0x041f,
"HCI_Hold_Mode",0x0801,
"HCI_Sniff_Mode",0x0803,
"HCI_Exit_Sniff_Mode",0x0804,
"HCI_Park_Mode",0x0805,
"HCI_Exit_Park_Mode",0x0806,
"HCI_QoS_Setup",0x0807,
"HCI_Role_Discovery",0x0809,
"HCI_Switch_Role",0x080b,
"HCI_Read_Link_Policy_Settings",0x080c,
"HCI_Write_Link_Policy_Settings",0x080d,
"HCI_Set_Event_Mask",0x0c01,
"HCI_Reset",0x0c03,
"HCI_Set_Event_Filter",0x0c05,
"HCI_Flush",0x0c08,
"HCI_Read_PIN_Type",0x0c09,
"HCI_Write_PIN_Type",0x0c0a,
"HCI_Create_New_Unit_Key",0x0c0b,
"HCI_Read_Stored_Link_Key",0x0c0d,
"HCI_Write_Stored_Link_Key",0x0c11,
"HCI_Delete_Stored_Link_Key",0x0c12,
"HCI_Change_Local_Name",0x0c13,
"HCI_Read_Local_Name",0x0c14,
"HCI_Read_Connection_Accept_Timeout",0x0c15,
"HCI_Write_Connection_Accept_Timeout",0x0c16,
"HCI_Read_Page_Timeout",0x0c17,
"HCI_Write_Page_Timeout",0x0c18,
"HCI_Read_Scan_Enable",0x0c19,
"HCI_Write_Scan_Enable",0x0c1a,
"HCI_Read_PageScan_Activity",0x0c1b,
"HCI_Write_PageScan_Activity",0x0c1c,
"HCI_Read_InquiryScan_Activity",0x0c1d,
"HCI_Write_InquiryScan_Activity",0x0c1e,
"HCI_Read_Authentication_Enable",0x0c1f,
"HCI_Write_Authentication_Enable",0x0c20,
"HCI_Read_Encryption_Mode",0x0c21,
"HCI_Write_Encryption_Mode",0x0c22,
"HCI_Read_Class_Of_Device",0x0c23,
"HCI_Write_Class_Of_Device",0x0c24,
"HCI_Read_Voice_Setting",0x0c25,
"HCI_Write_Voice_Setting",0x0c26,
"HCI_Read_Automatic_Flush_Timeout",0x0c27,
"HCI_Write_Automatic_Flush_Timeout",0x0c28,
"HCI_Read_Num_Broadcast_Retransmissions",0x0c29,
"HCI_Write_Num_Broadcast_Retransmissions",0x0c2a,
"HCI_Read_Hold_Mode_Activity",0x0c2b,
"HCI_Write_Hold_Mode_Activity",0x0c2c,
"HCI_Read_Transmit_Power_Level",0x0c2d,
"HCI_Read_SCO_Flow_Control_Enable",0x0c2e,
"HCI_Write_SCO_Flow_Control_Enable",0x0c2f,
"HCI_Set_Host_Controller_To_Host_Flow_Control",0x0c31,
"HCI_Host_Buffer_Size",0x0c33,
"HCI_Host_Number_Of_Completed_Packets",0x0c35,
"HCI_Read_Link_Supervision_Timeout",0x0c36,
"HCI_Write_Link_Supervision_Timeout",0x0c37,
"HCI_Read_Number_Of_Supported_IAC",0x0c38,
"HCI_Read_Current_IAC_LAP",0x0c39,
"HCI_Write_Current_IAC_LAP",0x0c3a,
"HCI_Read_Page_Scan_Period_Mode",0x0c3b,
"HCI_Write_Page_Scan_Period_Mode",0x0c3c,
"HCI_Read_Page_Scan_Mode",0x0c3d,
"HCI_Write_Page_Scan_Mode",0x0c3e,
"HCI_Read_Local_Version_Information",0x1001,
"HCI_Read_Local_Supported_Features",0x1003,
"HCI_Read_Buffer_Size",0x1005,
"HCI_Read_Country_Code",0x1007,
"HCI_Read_BD_ADDR",0x1009,
"HCI_Read_Failed_Contact_Counter",0x1401,
"HCI_Reset_Failed_Contact_Counter",0x1402,
"HCI_Get_Link_Quality",0x1403,
"HCI_Read_RSSI",0x1405,
"HCI_Read_Loopback_Mode",0x1801,
"HCI_Write_Loopback_Mode",0x1802,
"HCI_Enable_Device_Under_Test_Mode",0x1803,
0,0
},Events[]=
{
"HCI_Inquiry_Complete_Event",0x01,
"HCI_Inquiry_Result_Event",0x02,
"HCI_Connection_Complete_Event",0x03,
"HCI_Connection_Request_Event",0x04,
"HCI_Disconnection_Complete_Event",0x05,
"HCI_Authentication_Complete_Event",0x06,
"HCI_Remote_Name_Request_Complete_Event",0x07,
"HCI_Encryption_Change_Event",0x08,
"HCI_Change_Connection_Link_Key_Complete_Event",0x09,
"HCI_Master_Link_Key_Complete_Event",0x0a,
"HCI_Read_Remote_Supported_Features_Complete_Event",0x0b,
"HCI_Read_Remote_Version_Information_Complete_Event",0x0c,
"HCI_QoS_Setup_Complete_Event",0x0d,
"HCI_Command_Complete_Event",0x0e,
"HCI_Command_Status_Event",0x0f,
"HCI_Hardware_Error_Event",0x10,
"HCI_Flush_Occured_Event",0x11,
"HCI_Role_Change_Event",0x12,
"HCI_Number_Of_Completed_Packets_Event",0x13,
"HCI_Mode_Change_Event",0x14,
"HCI_Return_Link_Keys_Event",0x15,
"HCI_PIN_Code_Request_Event",0x16,
"HCI_Link_Key_Request_Event",0x17,
"HCI_Link_Key_Notification_Event",0x18,
"HCI_Loopback_Command_Event",0x19,
"HCI_Data_Buffer_Overflow_Event",0x1a,
"HCI_Max_Slots_Change_Event",0x1b,
"HCI_Read_Clock_Offset_Complete_Event",0x1c,
"HCI_Connection_Packet_Type_Changed_Event",0x1d,
"HCI_QoS_Violation_Event",0x1e,
"HCI_Page_Scan_Mode_Change_Event",0x1f,
"HCI_Page_Scan_Repetition_Mode_Change_Event",0x20,
0,0
};
char *FindEvent(int id)
{
for(int i=0; Events[i].Text;i++)
{
if(Events[i].Code==id)
return Events[i].Text;
}
return "HCI_???";
}
char *FindMessage(int id)
{
for(int i=0; Cmds[i].Text;i++)
{
if(Cmds[i].Code==id)
return Cmds[i].Text;
}
return "HCI_???";
}
typedef BOOL t_COM_Deinit(DWORD dwOpenData);
typedef BOOL t_COM_IOControl(
DWORD dwOpenData,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut
);
typedef HANDLE t_COM_Init(
ULONG Identifier
);
typedef HANDLE t_COM_Open(
HANDLE pContext,
DWORD AccessCode,
DWORD ShareMode
);
typedef BOOL t_COM_PowerDown(
HANDLE pContext
);
typedef BOOL t_COM_PowerUp(
HANDLE pContext
);
typedef ULONG t_COM_Read(
HANDLE pContext,
PUCHAR pTargetBuffer,
ULONG BufferLength
);
typedef ULONG t_COM_Write(
HANDLE COM_Write,
PUCHAR pSourceBytes,
ULONG NumberOfBytes
);
typedef BOOL t_COM_Close(
DWORD pContext
);
t_COM_Deinit *_COM_Deinit=0;
t_COM_IOControl *_COM_IOControl=0;
t_COM_Init *_COM_Init=0;
t_COM_Open *_COM_Open=0;
t_COM_PowerDown *_COM_PowerDown=0;
t_COM_PowerUp *_COM_PowerUp=0;
t_COM_Read *_COM_Read=0;
t_COM_Write *_COM_Write=0;
t_COM_Close *_COM_Close=0;
HANDLE hEvent=0;
char* Dump(const unsigned char *Buff, int count)
{
static char Out[65536];
char* p=Out;
if(count==0)
{
p+=sprintf(p,"\n");
return Out;
}
{
bool OnlyASCII=true;
for(int i=0; i<count; i++)
if((Buff[i]&255)<32||Buff[i]==127)
{
if((i==count-1 && Buff[i]==0)||Buff[i]==0x0d||Buff[i]==0x0a||Buff[i]==9)
continue;
OnlyASCII=false;
break;
}
if(OnlyASCII)
{
p+=sprintf(p,"--- Plain text\n");
for(int i=0; i<count; i++)
if(Buff[i]!='\r')
p+=sprintf(p,"%c",Buff[i]);
// if(Buff[count-1]!='\n')
// fprintf(Log,"\n");
p+=sprintf(p,"\n--- End of text\n\n");
return Out;
}
int Pos=0;
char OBuff[3*16+2+1];
char Str[17];
for(i=0; i<(count+15)/16; i++)
{
for(int j=0; j<16; j++,Pos++)
{
if(Pos<count)
{
sprintf(OBuff+3*j+(j>7),"%02X ",Buff[Pos]&255);
if((Buff[Pos]&255)<32||Buff[Pos]==127)
Str[j]='.';
else
Str[j]=Buff[Pos];
} else
{
sprintf(OBuff+3*j+(j>7)," ");
Str[j]=' ';
}
}
Str[16]=0;
OBuff[3*16+1]=0;
p+=sprintf(p,"%08X: %s \"%s\"\n",i*16,OBuff,Str);
}
}
p+=sprintf(p,"\n");
return Out;
}
bool IsLogging(void)
{
return true;
// return WaitForSingleObject(hEvent,0)==WAIT_OBJECT_0;
}
void LogData(PUCHAR Data, int NBytes)
{
if(!IsLogging())
return;
HANDLE h=CreateFile(L"\\logging.txt",GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
0,OPEN_ALWAYS,0,0);
if(h==INVALID_HANDLE_VALUE)
return;
SetFilePointer(h,0,0,FILE_END);
DWORD W;
WriteFile(h,Data,NBytes,&W,0);
CloseHandle(h);
}
void LogStr(char*Str)
{
LogData((PUCHAR)Str, strlen(Str));
LogData((PUCHAR)"\n",1);
}
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;
}
#undef SERIAL_API
#define SERIAL_API extern "C" __declspec(dllexport)
SERIAL_API BOOL COM_Close(
DWORD pContext
)
{
LogStr("COM_Close");
return _COM_Close(pContext);
}
SERIAL_API BOOL COM_Deinit(DWORD pContext)
{
LogStr("COM_Deinit");
return _COM_Deinit(pContext);
}
SERIAL_API BOOL COM_IOControl(
DWORD dwOpenData,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut
)
{
char Buff[1024];
sprintf(Buff,"COM_IOControl: %04X ",dwCode);
LogStr(Buff);
LogStr(Dump(pBufIn,dwLenIn));
return _COM_IOControl(
dwOpenData,
dwCode,
pBufIn,
dwLenIn,
pBufOut,
dwLenOut,
pdwActualOut);
}
SERIAL_API HANDLE COM_Init(
wchar_t* Identifier
)
{
LogStr("COM_Init");
if(hEvent==0)
{
hEvent=CreateEvent(0,TRUE,FALSE,L"seRILal logging event");
HINSTANCE H=LoadLibrary(L"Serial_BTUR.dll");
if(H==0)
{
LogStr("Error loading DLL");
return 0;
}
_COM_Deinit=(t_COM_Deinit*)GetProcAddress(H,L"COM_Deinit");
if(_COM_Deinit==0)
LogStr("COM_Deinit==0");
_COM_IOControl=(t_COM_IOControl*)GetProcAddress(H,L"COM_IOControl");
if(_COM_IOControl==0)
LogStr("COM_IOControl==0");
_COM_Init=(t_COM_Init*)GetProcAddress(H,L"COM_Init");
if(_COM_Init==0)
LogStr("COM_Init==0");
_COM_Open=(t_COM_Open*)GetProcAddress(H,L"COM_Open");
if(_COM_Open==0)
LogStr("COM_Open==0");
_COM_PowerDown=(t_COM_PowerDown*)GetProcAddress(H,L"COM_PowerDown");
if(_COM_PowerDown==0)
LogStr("COM_PowerDown==0");
_COM_PowerUp=(t_COM_PowerUp*)GetProcAddress(H,L"COM_PowerUp");
if(_COM_PowerUp==0)
LogStr("COM_PowerUp==0");
_COM_Read=(t_COM_Read*)GetProcAddress(H,L"COM_Read");
if(_COM_Read==0)
LogStr("COM_Read==0");
_COM_Write=(t_COM_Write*)GetProcAddress(H,L"COM_Write");
if(_COM_Write==0)
LogStr("COM_Write==0");
_COM_Close=(t_COM_Close*)GetProcAddress(H,L"COM_Close");
if(_COM_Close==0)
LogStr("COM_Close==0");
LogStr("DLL loaded");
}
HANDLE H=_COM_Init((DWORD)Identifier);
return H;
}
SERIAL_API HANDLE COM_Open(
HANDLE pContext,
DWORD AccessCode,
DWORD ShareMode
)
{
LogStr("COM_Open");
return _COM_Open(
pContext,
AccessCode,
ShareMode);
}
SERIAL_API BOOL COM_PowerDown(
HANDLE pContext
)
{
LogStr("COM_PowerDown");
return _COM_PowerDown(pContext);
}
SERIAL_API BOOL COM_PowerUp(
HANDLE pContext
)
{
LogStr("COM_PowerUp");
return _COM_PowerUp(pContext);
}
int SCO_Handle=0;
SERIAL_API ULONG COM_Read(
HANDLE pContext,
PUCHAR pTargetBuffer,
ULONG BufferLength
)
{
int L=_COM_Read(
pContext,
pTargetBuffer,
BufferLength);
if(L)
{
LogStr("COM_Read");
if(L>2&&pTargetBuffer[0]==4)
{
char Buff[1024];
int m=pTargetBuffer[1];
sprintf(Buff,"%s - %02X",FindEvent(m),m);
LogStr(Buff);
if(pTargetBuffer[1]==3 && pTargetBuffer[3]==0 && pTargetBuffer[12]==0)
{
LogStr("SCO connection");
SCO_Handle=pTargetBuffer[4]+pTargetBuffer[5]*256;
}
}
LogStr(Dump(pTargetBuffer,L));
}
return L;
}
SERIAL_API ULONG COM_Write(
HANDLE pContext,
PUCHAR pSourceBytes,
int NumberOfBytes
)
{
LogStr("COM_Write");
if(SCO_Handle)
{
LogStr("sending SCO packet");
char Buffer[256];
Buffer[0]=SCO_Handle&255;
Buffer[1]=SCO_Handle/255;
Buffer[2]=240;
for(int i=0; i<240; i++)
Buffer[3+i]=(i&2)?127:0;
_COM_Write(
pContext,
(unsigned char*)"\x03",
1);
_COM_Write(
pContext,
(unsigned char*)Buffer,
240+3);
SCO_Handle=0;
}
if(NumberOfBytes>2)
{
char Buff[1024];
int m=pSourceBytes[1]*256+pSourceBytes[0];
sprintf(Buff,"%s - %04X",FindMessage(m),m);
LogStr(Buff);
}
LogStr(Dump(pSourceBytes,NumberOfBytes));
return _COM_Write(
pContext,
pSourceBytes,
NumberOfBytes);
}
SERIAL_API ULONG COM_Seek()
{
return -1;
}
Thanks for your help. The reason I am porting my Dll from Services.exe to Device.exe is because I need it to run continuosly and when running in Services.exe when the device suspends of course no CPU time. That is, I was hoping to implement the Dll as a driver and catch the PowerDown message and prevent it from happening.
I noticed that in the MSDN example the PowerDown method is void but in yours it returns Bool. To prevent the power down do I convert the method to return a false bool value? Can this functionality be done?
Regards Gerard
GerardRaciti said:
I noticed that in the MSDN example the PowerDown method is void but in yours it returns Bool.
Click to expand...
Click to collapse
Don't always trust MSDN regarding Windows CE. I've taken these prototypes from some of MS own drivers.
You can prevent device from sleeping from your program using this method:
http://msdn.microsoft.com/library/d.../html/ppc_programming_pocket_pc_2002_lfyy.asp
That was the method I used originally to tackle this problem but it consumed too much power leaving the screen in that dimmed state.
I had the understanding that if I implemented my Dll in a device driver the screen could go blank but the device would only go into "sleep" mode where drivers would still receive CPU time as long as they responded to the PowerDown function.
Do you know if this is possible or am I wasting my time?
I don't know. I never worked with power levels. But probably this is possible in driver with functions SetPowerRequirement and DevicePowerNotify. But this would work only if device supports D1 (low on) power mode. Otherwise I think you would not notice any difference with keeping the device always on and shutting down LCD+backlight.
Thanks again for your help.
I have managed to port my service into a device driver but am having trouble handling Power Management issues. It seems as though it is in my Dll attempting to prevent a device suspension which is crashing the device. If I dont attempt to prevent suspend mode or set power requirements the Dll is quite stable. If anyone has any experience with Device driver power management or can point me in the right direction it would be much appreciated.
Regards Gerard
you may try to ask in microsoft newsgroups like microsoft.public.windowsce.app.development or microsoft.public.windowsce.platbuilder or similar
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.
Hi All,
I am developing a VOIP application for Windows Mobile. I want the user to switch the between the Speaker and Earpiece of the Mobile Phone. I have searched the Forum and found the following link
http://teksoftco.com/forum/viewtopic.php?p=1909
As you know we have to use LoadLibrary and GetProcAddress to access the RIL APIs in Windows Mobile. I have written following piece of code for this i.e.
Code:
HRIL hRIL;
bool speakerphone = true; // false;
HRESULT result = RIL_Initialize(1, ResultCallback, NotifyCallback, RIL_NCLASS_MISC, 0, &hRIL);
if (result != S_OK) {
wchar_t buffer[200];
wsprintf(buffer, L"Could not open RIL, error=0x%x", result);
AfxMessageBox(buffer);
return;
}
RILAUDIODEVICEINFO info;
info.cbSize = sizeof(info);
info.dwParams = RIL_PARAM_ADI_ALL; // RIL_PARAM_ADI_TXDEVICE;
info.dwRxDevice = RIL_AUDIO_HANDSET;
info.dwTxDevice = speakerphone ? RIL_AUDIO_NONE : RIL_AUDIO_HANDSET;
result = RIL_SetAudioDevices(hRIL, &info);
if (result != S_OK) {
wchar_t buffer[200];
wsprintf(buffer, L"Could not open RIL, error=0x%x", result);
AfxMessageBox(buffer);
}
RIL_Deinitialize(hRIL);
But this doesn't seems to work, i.e. some time it causes both the audio input and output to halt, sometime audio input is halted (i.e. no voice is heard on the other end).
I have also tried another techniques to accomplish this task, like:
Technique 2
--------------
Code:
#define MM_WOM_FORCESPEAKER (WM_USER+2)
static void SetSpeakerMode(bool speakerphone)
{
MMRESULT result = waveOutMessage((HWAVEOUT)0, MM_WOM_FORCESPEAKER, speakerphone, 0);
if (result != MMSYSERR_NOERROR) {
wchar_t buffer[200];
wsprintf(buffer, L"Could not do speakerphone switch, error=%u", result);
AfxMessageBox(buffer);
}
}
Technique 3
--------------
Code:
/* Stuff from Wavedev.h */
#define IOCTL_WAV_MESSAGE 0x001d000c
typedef struct {
UINT uDeviceId;
UINT uMsg;
DWORD dwUser;
DWORD dwParam1;
DWORD dwParam2;
} MMDRV_MESSAGE_PARAMS;
/* End of Wavedev.h extract */
class WavDevice
{
private:
HANDLE hWavDev;
public:
WavDevice()
{
hWavDev = CreateFile(TEXT("WAV1:"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hWavDev == INVALID_HANDLE_VALUE) {
wchar_t buffer[200];
wsprintf(buffer, L"Could not open device, error=%u", GetLastError());
AfxMessageBox(buffer);
}
}
~WavDevice()
{
if (hWavDev != INVALID_HANDLE_VALUE)
CloseHandle(hWavDev);
}
bool SendMessage(UINT uMsg, DWORD dwParam1 = 0, DWORD dwParam2 = 0)
{
if (hWavDev == INVALID_HANDLE_VALUE)
return false;
DWORD dwRet = 0, dwOut;
MMDRV_MESSAGE_PARAMS mp;
memset(&mp,0,sizeof(mp));
mp.uMsg = uMsg;
mp.dwParam1 = dwParam1;
mp.dwParam2 = dwParam2;
if (DeviceIoControl(hWavDev, IOCTL_WAV_MESSAGE, &mp, sizeof(mp), &dwOut, sizeof(dwOut), &dwRet, 0))
return true;
wchar_t buffer[200];
wsprintf(buffer, L"Could not do speakerphone switch, error=%u", GetLastError());
AfxMessageBox(buffer);
return false;
}
};
static void SetSpeakerMode(bool speakerphone)
{
WavDevice wd;
if (!wd.SendMessage(1002, speakerphone ? 0 : 2))
return;
if (!wd.SendMessage(1012, speakerphone ? 0 : 1))
return;
if (speakerphone && !wd.SendMessage(1013))
return;
wd.SendMessage(1000, speakerphone ? 2 : 4, speakerphone ? 0 : 7);
}
Technique 4
--------------
Code:
class OsSvcsDll
{
private:
HMODULE hDLL;
typedef HRESULT (* SetSpeakerModeFn)(DWORD mode);
SetSpeakerModeFn pfnSetSpeakerMode;
public:
OsSvcsDll()
{
hDLL = LoadLibrary(L"\\windows\\ossvcs.dll");
if (hDLL == NULL) {
wchar_t buffer[200];
wsprintf(buffer, L"Could not open DLL, error=%u", GetLastError());
AfxMessageBox(buffer);
}
pfnSetSpeakerMode = (SetSpeakerModeFn)GetProcAddress(hDLL, (LPCTSTR)218);
if (pfnSetSpeakerMode == NULL) {
wchar_t buffer[200];
wsprintf(buffer, L"Could not open DLL, error=%u", GetLastError());
AfxMessageBox(buffer);
}
}
~OsSvcsDll()
{
if (hDLL != NULL)
FreeLibrary(hDLL);
}
bool SetSpeakerMode(DWORD speakerphone)
{
if (pfnSetSpeakerMode == NULL)
return false;
HRESULT result = pfnSetSpeakerMode(speakerphone);
if (result == 0)
return true;
wchar_t buffer[200];
wsprintf(buffer, L"Could not do speakerphone switch, error=0x%x", result);
AfxMessageBox(buffer);
return false;
}
};
static void SetSpeakerMode(bool speakerphone)
{
OsSvcsDll dll;
dll.SetSpeakerMode(speakerphone ? 1 : 0);
}
But no procedure seems to work properly.
Can you please guide me where i am going wrong or some other way of achieving this.
I am using
Visual C++ MFC Dialog based Application
Visual Studio 2008
Windows Mobile 6 SDK For PocketPC
I have tested the above mentioned sample on
HTC Touch
Sony Erricsson XPeria
Waiting for response.
Regards,
Ghazanfar Ali
Regards,
Ghazanfar Ali
I want to add to HKLM\init an all purpose application launcher (CE 6.0 device has persistent registry):
Code:
[HKEY_LOCAL_MACHINE\Init]
"Depend199"=hex:00,14,00,1e,00,60
[HKEY_LOCAL_MACHINE\Init]
"Launch199"="\NandFlash\CeLaunchAppsAtBootTime.exe"
[HKEY_CURRENT_USER\Startup]
"Process1"="\NandFlash\SetBackLight.exe"
"Process1Delay"=dword:0
The launcher's code is
Code:
#include <Windows.h>
#if defined(OutputDebugString)
#undef OutputDebugString
void OutputDebugString(LPTSTR lpText)
{}
#endif
BOOL IsAPIReady(DWORD hAPI);
void WalkStartupKeys(void);
DWORD WINAPI ProcessThread(LPVOID lpParameter);
#define MAX_APPSTART_KEYNAME 256
typedef struct _ProcessStruct {
WCHAR szName[MAX_APPSTART_KEYNAME];
DWORD dwDelay;
} PROCESS_STRUCT,*LPPROCESS_STRUCT;
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
int nLaunchCode = -1;
// Quick check to see whether we were called from within HKLM\init -> by default HKLM\init passes the lauch code
if(lpCmdLine && *lpCmdLine)
{
// MessageBox(NULL, lpCmdLine ,NULL,MB_OK);
nLaunchCode = _ttoi( (const TCHAR *) lpCmdLine);
}
else
{
// MessageBox(NULL, _T("No argumets passed"),NULL,MB_OK);
}
//Wait for system has completely initialized
BOOL success = FALSE;
int i = 0;
while((!IsAPIReady(SH_FILESYS_APIS)) && (i++ < 50))
{
Sleep(200);
}
success = (i < 50);
if(success)
{
i = 0;
while((!IsAPIReady(SH_DEVMGR_APIS))&& (i++ < 50))
{
Sleep(200);
}
success = (i < 50);
if(success)
{
i = 0;
while((!IsAPIReady(SH_SHELL))&& (i++ < 50))
{
Sleep(200);
}
success = (i < 50);
if(success)
{
i = 0;
while((!IsAPIReady(SH_WMGR))&& (i++ < 50))
{
Sleep(200);
}
success = (i < 50);
if(success)
{
i = 0;
while((!IsAPIReady(SH_GDI))&& (i++ < 50))
{
Sleep(200);
}
success = (i < 50);
}
}
}
}
if(nLaunchCode != -1)
{
// Since this is application is launched through the registry HKLM\Init we need to call SignalStarted passing in the command line parameter
SignalStarted((DWORD) nLaunchCode);
}
//If system has completely initialized
if( success)
{
WalkStartupKeys();
}
return (0);
}
void WalkStartupKeys(void)
{
HKEY hKey;
WCHAR szName[MAX_APPSTART_KEYNAME];
WCHAR szVal[MAX_APPSTART_KEYNAME];
WCHAR szDelay[MAX_APPSTART_KEYNAME];
DWORD dwType, dwNameSize, dwValSize, i,dwDelay;
DWORD dwMaxTimeout=0;
HANDLE hWaitThread=NULL;
HANDLE ThreadHandles[100];
int iThreadCount=0;
if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Startup"), 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
return;
}
dwNameSize = MAX_APPSTART_KEYNAME;
dwValSize = MAX_APPSTART_KEYNAME * sizeof(WCHAR);
i = 0;
while (RegEnumValue(hKey, i, szName, &dwNameSize, 0, &dwType,(LPBYTE)szVal, &dwValSize) == ERROR_SUCCESS) {
if ((dwType == REG_SZ) && !wcsncmp(szName, TEXT("Process"), 7)) { // 7 for "Process"
// szval
wsprintf(szDelay,L"%sDelay",szName);
dwValSize=sizeof(dwDelay);
if (ERROR_SUCCESS == RegQueryValueEx(hKey,szDelay,0,&dwType,(LPBYTE)&dwDelay,&dwValSize)) {
// we now have the process name and the process delay - spawn a thread to "Sleep" and then create the process.
LPPROCESS_STRUCT ps=(LPPROCESS_STRUCT) LocalAlloc( LMEM_FIXED , sizeof( PROCESS_STRUCT));
ps->dwDelay=dwDelay;
wcscpy(ps->szName,szVal);
DWORD dwThreadID;
OutputDebugString(L"Creating Thread...\n");
HANDLE hThread=CreateThread(NULL,0,ProcessThread,(LPVOID)ps,0,&dwThreadID);
ThreadHandles[iThreadCount++]=hThread;
if (dwDelay > dwMaxTimeout) {
hWaitThread=hThread;
dwMaxTimeout=dwDelay;
}
LocalFree((HLOCAL) ps);
}
}
dwNameSize = MAX_APPSTART_KEYNAME;
dwValSize = MAX_APPSTART_KEYNAME * sizeof(WCHAR);
i++;
}
// wait on the thread with the longest delay.
DWORD dwWait=WaitForSingleObject(hWaitThread,INFINITE);
if (WAIT_FAILED == dwWait) {
OutputDebugString(L"Wait Failed!\n");
}
for(int x=0;x < iThreadCount;x++) {
CloseHandle(ThreadHandles[x]);
}
RegCloseKey(hKey);
}
DWORD WINAPI ProcessThread(LPVOID lpParameter)
{
TCHAR tcModuleName[MAX_APPSTART_KEYNAME];
OutputDebugString(L"Thread Created... Sleeping\n");
LPPROCESS_STRUCT ps=(LPPROCESS_STRUCT)lpParameter;
Sleep(ps->dwDelay); // Wait for delay period
OutputDebugString(L"Done Sleeping...\n");
PROCESS_INFORMATION pi;
STARTUPINFO si;
si.cb=sizeof(si);
OutputDebugString(L"Creating Process ");
OutputDebugString(ps->szName);
OutputDebugString(L"\n");
wcscpy(tcModuleName,ps->szName);
TCHAR *tcPtrSpace=wcsrchr(ps->szName,L' '); // Launch command has a space, assume command line.
if (NULL != tcPtrSpace) {
tcModuleName[lstrlen(ps->szName)-lstrlen(tcPtrSpace)]=0x00; // overwrite the space with null, break the app and cmd line.
tcPtrSpace++; // move past space character.
}
CreateProcess( tcModuleName, // Module Name
tcPtrSpace, // Command line -- NULL or PTR to command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi ); // Pointer to PROCESS_INFORMATION structure
OutputDebugString(L"Thread Exiting...\n");
return 0;
}
which compiled errorfree
Added the registry entries as shown above, copied the launcher's exe in default location, rebootet device. Nothing happened, means executable defined as
Code:
[HKEY_CURRENT_USER\Startup]
"Process1"="\NandFlash\SetBackLight.exe"
wasn't run at all.
Does anybody have an idea, where the error is? Any help appreciated. Thanks for reading.