Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Monday, January 26, 2009

Message send/receive between DLL and EXE

1. Message.h

#pragma once
#include "enums.h"
class CMessages
{
public:
static DWORD sm_dwNotificationMessage;
static HWND sm_hWndNotification;
static void PostMessage(NOTIFICATION_
MESSAGES message,LPARAM info=0);
};

//enum.h
enum NOTIFICATION_MESSAGES
{
DISCOVERY_COMPLETE=0x100,
PAIRING_COMPLETE,
PAIRING_ERROR,
DISCOVERY_ERROR,
SERVICE_DISCOVERY_COMPLETE,
SERVICE_DISCOVERY_ERROR,
};

2. Message.cpp

#include "StdAfx.h"
#include "Messages.h"

DWORD CMessages::sm_dwNotificationMessage = RegisterWindowMessage(_T("Notification2A23463D-0006-4ec7-89CC-0A27AA71C4A8"));
HWND CMessages::sm_hWndNotification = NULL;

void CMessages::PostMessage(NOTIFICATION_MESSAGES message,LPARAM info)
{
::PostMessage(CMessages::sm_hWndNotification,CMessages::sm_dwNotificationMessage,message,info);
}

3. Usage:

CMessages::PostMessage(DISCOVERY_ERROR,iError);

Exported functions:

MYLIB_API unsigned WINAPI GetNotificationMessage();
MYLIB_API void WINAPI SetNotificationWindow(HWND hWndNotify) ;

CMessages m_CMessages;
HWND GetNotificationWnd() {return m_CMessages.sm_hWndNotification;}
DWORD GetNotificationMessage() {return m_CMessages.sm_dwNotificationMessage;}
void SetNotificationWindow(HWND hWndNotify) {m_CMessages.sm_hWndNotification = hWndNotify;}

4. In exe, using C#

#region MessageFunctions
//> ---------------------------------------------------------------------------
//> Class: NotificationWindow
//> Purpose: target window for bluetooth device events
//> ---------------------------------------------------------------------------
public class NotificationWindow : MessageWindow
{
// Create an instance of the form.
private Form1 m_FormConnWizard;

// Save a reference to the form so it can
// be notified when messages are received.
public NotificationWindow(Form1 formConnWizard)
{
this.m_FormConnWizard = formConnWizard;
}

// handle window messages from the bluetooth dll
protected override void WndProc(ref Message msg)
{
if (msg.Msg == m_FormConnWizard.GetMyNotificationMessage())
{
// call back to the form to handle this message
m_FormConnWizard.NotificationMessage(msg);
}
else{}
// Call the base WndProc method
// to process any messages not handled.
base.WndProc(ref msg);
}
}
private int GetMyNotificationMessage()
{
return (int)GetNotificationMessage();
}
private void NotificationMessage(Message msg)
{
switch ((uint)msg.WParam)
{
case (uint)NOTIFICATION_MESSAGES.DISCOVERY_COMPLETE:
{
KillSearchingTimer();
MessageBox.Show("DISCOVERY COMPLETE!");
break;
}
case (uint)NOTIFICATION_MESSAGES.DISCOVERY_ERROR:
{
//dx: revise the message
MessageBox.Show("...");
break;
}
case (uint)NOTIFICATION_MESSAGES.SERVICE_DISCOVERY_COMPLETE:
{

break;
}
case (uint)NOTIFICATION_MESSAGES.SERVICE_DISCOVERY_ERROR:
{
//MessageBox.Show(Properties.Resources.strDiscoveryError, "Service Discovery Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
break;
}

}

}
#endregion

public partial class Form1 : Form
{
NotificationWindow m_NotificationWindow;
public Form1()
{
m_NotificationWindow = new NotificationWindow(this);
SetNotificationWindow(m_NotificationWindow.Hwnd);

InitializeComponent();
}
..
}

[DllImport("xxx.dll", EntryPoint = "SetNotificationWindow", SetLastError = true)]
private extern static void SetNotificationWindow(IntPtr hWndNotify);

[DllImport("xxx.dll", EntryPoint = "GetNotificationMessage", SetLastError = true)]
private extern static uint GetNotificationMessage();

Wednesday, January 21, 2009

How to play a sound

http://www.bobpowell.net/playsnd.htm

Windows Forms classes are bereft of a simple way to play sounds. This glaring oversight is however easily rectified with a little bit of platform-invoke interop.

There are a couple of ways to do this. The first method requires the multimedia API sndPlaySnd and a few constants defined but once this is done you can add sounds to your Windows Forms applications easily. This API is a subset of the PlaySound API which can also be accessed through interop.

First you need to import the sndPlaySound or PlaySound API from the multimedia DLL. Interop enables us to import these signatures in a number of ways. For example, in some configurations the sndPlaySound method can be passed the address of a .WAV sound stored in memory but C# and VB are a bit finicky about casting strings to pointers so we can overload the p/invoke import statement to provide a version of the method signature that accepts an IntPtr instead of a string.

[DllImport("Winmm.dll")]

static extern int sndPlaySound(string lpszSound, int fuSound);

[DllImport("Winmm.dll")]

static extern int sndPlaySound(IntPtr ptr, int fuSound);

_

Shared Function sndPlaySound(lpszSound As String, fuSound As Integer) As Integer

_

Shared Function sndPlaySound(ptr As IntPtr, fuSound As Integer) As Integer

The constants required for the multimedia functions can be converted from the old C++ header files.

enum soundConstants

{

SND_SYNC = 0x0000, /* play synchronously (default) */

SND_ASYNC = 0x0001, /* play asynchronously */

SND_NODEFAULT = 0x0002, /* silence (!default) if sound not found */

SND_MEMORY = 0x0004, /* pszSound points to a memory file */

SND_LOOP = 0x0008, /* loop the sound until next sndPlaySound */

SND_NOSTOP = 0x0010, /* don't stop any currently playing sound */

SND_NOWAIT = 0x00002000, /* don't wait if the driver is busy */

SND_ALIAS = 0x00010000, /* name is a registry alias */

SND_ALIAS_ID = 0x00110000, /* alias is a predefined ID */

SND_FILENAME = 0x00020000, /* name is file name */

SND_RESOURCE = 0x00040004, /* name is resource name or atom */

SND_PURGE = 0x0040, /* purge non-static events for task */

SND_APPLICATION = 0x0080, /* look for application specific association */

}

Enum soundConstants

SND_SYNC = &H0 ' play synchronously (default)

SND_ASYNC = &H1 ' play asynchronously

SND_NODEFAULT = &H2 ' silence (!default) if sound not found

SND_MEMORY = &H4 ' pszSound points to a memory file

SND_LOOP = &H8 ' loop the sound until next sndPlaySound

SND_NOSTOP = &H10 ' don't stop any currently playing sound

SND_NOWAIT = &H2000 ' don't wait if the driver is busy

SND_ALIAS = &H10000 ' name is a registry alias

SND_ALIAS_ID = &H110000 ' alias is a predefined ID

SND_FILENAME = &H20000 ' name is file name

SND_RESOURCE = &H40004 ' name is resource name or atom

SND_PURGE = &H40 ' purge non-static events for task

SND_APPLICATION = &H80 ' look for application specific association

End Enum 'soundConstants

Then, to play a sound simply call the method and provide the sound file.

sndPlaySound(@"C:\Sounds\Explosion1.wav", (int)soundConstants.SND_ASYNC);

sndPlaySound("C:\Sounds\Explosion1.wav", CInt(soundConstants.SND_ASYNC))

You can embed a .wav file into your application by adding it to the application and then setting the build action to "embedded resource" in the solution item properties. This enables you to ship an application with the sounds built into the resources and so there are no extra files to distribute.

Getting at the file is a little more complex than simply nominating the filename an must be done using a Garbage Collector handle (GCHandle) and a pinned array. The following listing assumes a file has been embedded in the resources and is accessible as a stream.

Stream s=this.GetType().Assembly.GetManifestResourceStream("PlaySound.win_1.wav");

byte[] buffer=new byte[s.Length];

s.Read(buffer,0,(int)s.Length);

GCHandle h=GCHandle.Alloc(buffer);

IntPtr ptr=Marshal.UnsafeAddrOfPinnedArrayElement(buffer,0);

sndPlaySound(ptr,(int)soundConstants.SND_MEMORY | (int)soundConstants.SND_ASYNC);

h.Free();

Dim s As Stream = Me.GetType().Assembly.GetManifestResourceStream("PlaySoundVB.win_1.wav")

Dim buffer(s.Length) As Byte

s.Read(buffer, 0, CInt(s.Length))

Dim h As GCHandle = GCHandle.Alloc(buffer)

Dim ptr As IntPtr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0)

sndPlaySound(ptr, CInt(soundConstants.SND_MEMORY) Or CInt(soundConstants.SND_ASYNC))

-----------------------------------------------------------------------------------------

  1. // Include file
  2. #include "mmsystem.h"
  3. // Link to this library
  4. #pragma comment( lib, "winmm.lib" )
  5. int main( int argc, char **argv )
  6. {
  7. // Will block till the whole file is played, use SND_ASYNC to play asynchronously
  8. sndPlaySound( "c://windows//media//ding.wav", SND_SYNC );
  9. // Play for ever, should use SND_ASYNC
  10. sndPlaySound( "c://windows//media//ding.wav", SND_ASYNC|SND_LOOP );
  11. // Sleep for 5 seconds
  12. Sleep( 5000 );
  13. // Enough is enough stop making that stupid noise
  14. sndPlaySound( NULL, SND_SYNC );
  15. return 0;
  16. }// End main

Thursday, January 15, 2009

How to create REG_MULTI_SZ and REG_BINARY in C++ and C#

1. REG_MULTI_SZ

C#:

string[] ConfigurationString = new string[8];
ConfigurationString[0] = Location;
ConfigurationString[1] = LocalCalls;
ConfigurationString[2] = LongDistanceCalls;
ConfigurationString[3] = InternationalCalls;
ConfigurationString[4] = AreaCode;
ConfigurationString[5] = DisableCallWaitingSequence;
ConfigurationString[6] = CountryCode;
ConfigurationString[7] = ToneOrPulse;

RegistryKey rk = Registry.CurrentUser;
using (RegistryKey rk1 = rk.CreateSubKey("ControlPanel\
\Dial\\Locations"))
{
rk1.SetValue(KeyName, ConfigurationString);
rk1.Close();
}

C++: (not tested yet!)

HKEY hKey = NULL;
DWORD dataType = REG_MULTI_SZ;
LONG retVal = 0;
LONG ConfigurationStringSize = 512;
WCHAR *ConfigurationString = new WCHAR[ConfigurationStringSize];
memset(ConfigurationString,'\0',512);

// Build the configuration string.
wcscat(ConfigurationString, Location);
wcscat(ConfigurationString, TEXT("$"));

wcscat(ConfigurationString, LocalCalls);
wcscat(ConfigurationString, TEXT("$"));

wcscat(ConfigurationString, LongDistanceCalls);
wcscat(ConfigurationString, TEXT("$"));

wcscat(ConfigurationString, InternationalCalls);
wcscat(ConfigurationString, TEXT("$"));

wcscat(ConfigurationString, AreaCode);
wcscat(ConfigurationString, TEXT("$"));

wcscat(ConfigurationString, DisableCallWaitingSequence);
wcscat(ConfigurationString, TEXT("$"));

wcscat(ConfigurationString, CountryCode);
wcscat(ConfigurationString, TEXT("$"));

wcscat(ConfigurationString, ToneOrPulse);
wcscat(ConfigurationString, TEXT("$"));

// Format the string correctly.
int ConfigStringLen = wcslen(ConfigurationString);
for(int x = 0; x < ConfigStringLen; ++x)
{
if(ConfigurationString[x] == '$')
ConfigurationString[x] = '\0';
}

// Open the registry key.
retVal = RegOpenKeyEx(HKEY_CURRENT_USER , TEXT("ControlPanel\\Dial\\Locations"), 0, KEY_READ, &hKey);
if(retVal != ERROR_SUCCESS)
{
delete [] ConfigurationString;
return false;
}

// Set the value of the key.
retVal = RegSetValueEx(hKey, KeyName, NULL, dataType, (PBYTE)ConfigurationString, ConfigurationStringSize);
RegCloseKey(hKey);

delete [] ConfigurationString;

return retVal != ERROR_SUCCESS ? false : true;
-------------------------------------------------------------------------------
2. REG_BINARY

C#:
private bool GetBinaryBluetoothAddress(string sBluetoothAddress, ref byte[] bBTAddress)
{
try
{
//00:03:c9:56:0c:EE
string[] sTmp = sBluetoothAddress.Split(':');
bBTAddress[0] = Convert.ToByte(sTmp[5], 16);
bBTAddress[1] = Convert.ToByte(sTmp[4], 16);
bBTAddress[2] = Convert.ToByte(sTmp[3], 16);
bBTAddress[3] = Convert.ToByte(sTmp[2], 16);
bBTAddress[4] = Convert.ToByte(sTmp[1], 16);
bBTAddress[5] = Convert.ToByte(sTmp[0], 16);
bBTAddress[6] = 0;
bBTAddress[7] = 0;

return true;
}
catch
{
return false;
}
}

RegistryKey rk = Registry.LocalMachine;
using (RegistryKey rk1 = rk.CreateSubKey("\\Software\\dx"))
{
byte[] bA = new byte[8];
if (GetBinaryBluetoothAddress("00:03:c9:56:0c:EE", ref bA))
{
rk1.SetValue("dxaddress", bA);
MessageBox.Show("Good!");
}
else
MessageBox.Show("Failed!");

rk1.Close();
}
rk.Close();

C++:

unsigned char epwd[9];

//set epwd here

RegSetValueEx(hKey,"keyname",0,REG_BINARY,(LPBYTE)&epwd,8);

Tuesday, January 13, 2009

How to set Bluetooth ActiveSync Connection

Method 1: use ras to setup the dialing parameters
SetActiveSyncDialingParameters();


private void SetActiveSyncDialingParameters
()
{
int dwSize;
char[] bSP = new char[512];
RASENTRY RasEntry;
RasEntry = new RASENTRY();

RASDIALPARAMS RasDialParams;
RasDialParams = new RASDIALPARAMS();

dwSize = Marshal.SizeOf(typeof(RASENTRY));
RasEntry.dwSize = dwSize;
uint temp = 512;


//MessageBox.Show("Attempting RASGetEntries");
uint dwGetEntry = 0;
dwGetEntry = RasConnection.RasGetEntryProperties("", "",
ref RasEntry, ref dwSize, bSP, ref temp);
if (dwGetEntry >= 1)
{
MessageBox.Show("Unable to retrieve information:" + dwGetEntry.ToString()); //passed after readjust struc
//return;

}
///* RASENTRY 'dwfOptions' bit flags.
//*/
//#define RASEO_UseCountryAndAreaCodes 0x00000001
//#define RASEO_SpecificIpAddr 0x00000002
//#define RASEO_SpecificNameServers 0x00000004
//#define RASEO_IpHeaderCompression 0x00000008
//#define RASEO_RemoteDefaultGateway 0x00000010
//#define RASEO_DisableLcpExtensions 0x00000020
//#define RASEO_TerminalBeforeDial 0x00000040
//#define RASEO_TerminalAfterDial 0x00000080
//#define RASEO_ModemLights 0x00000100
//#define RASEO_SwCompression 0x00000200
//#define RASEO_RequireEncryptedPw 0x00000400
//#define RASEO_RequireMsEncryptedPw 0x00000800
//#define RASEO_RequireDataEncryption 0x00001000
//#define RASEO_NetworkLogon 0x00002000
//#define RASEO_UseLogonCredentials 0x00004000
//#define RASEO_PromoteAlternates 0x00008000
//#define RASEO_SecureLocalFiles 0x00010000
//#define RASEO_DialAsLocalCall 0x00020000

//#define RASEO_ProhibitPAP 0x00040000
//#define RASEO_ProhibitCHAP 0x00080000
//#define RASEO_ProhibitMsCHAP 0x00100000
//#define RASEO_ProhibitMsCHAP2 0x00200000
//#define RASEO_ProhibitEAP 0x00400000
//#define RASEO_PreviewUserPw 0x01000000
//#define RASEO_NoUserPwRetryDialog 0x02000000
//#define RASEO_CustomScript 0x80000000

//RasEntry.dwfOptions &= ~(RASEO_SpecificNameServers|RASEO_SpecificIpAddr|
// RASEO_IpHeaderCompression|RASEO_SwCompression|RASEO_UseCountryAndAreaCodes);

RasEntry.dwfOptions &= ~(0x00000004 | 0x00000002 | 0x00000008 | 0x00000200 | 0x00000001);

RasEntry.szDeviceName = "BluetoothSYN";
RasEntry.szDeviceType = "direct";

dwGetEntry = RasConnection.RasSetEntryProperties(null, "Bluetooth", ref RasEntry, dwSize, null, 0);
if (dwGetEntry >= 1)
{
MessageBox.Show("Unable to RasSetEntryProperties:" + dwGetEntry.ToString()); //621;passed after change first parameter from "" to null
//return;
}

RasDialParams.dwSize = (int )Marshal.SizeOf (typeof(RASDIALPARAMS));
RasDialParams.szEntryName = "Bluetooth";
RasDialParams.szUserName = "guest";
RasDialParams.szPassword = "guest";


dwGetEntry = RasConnection.RasSetEntryDialParams(null, ref RasDialParams, false);
if (dwGetEntry >= 1)
{
MessageBox.Show("Unable to RasSetEntryDialParams:" + dwGetEntry.ToString()); //610:passed after change first parameter from "" to null
//return;
}
}

Method 2: directly go to registry to set up ras phone book
RASPHONEENTRY rs = new RASPHONEENTRY();
#if (UseCOM1)
rs.CreateRasEntry("BluetoothCOM1", 1, ref m_iOldValue1, ref m_sOldValue2);
#else
rs.CreateRasEntry("BluetoothCOM2", 2, ref m_iOldValue1, ref m_sOldValue2);
#endif
//timer start
m_ActiveSyncTimer = new System.Windows.Forms.Timer();
m_ActiveSyncTimer.Tick += new EventHandler(ActiveSyncTimerEventProcessor);
m_ActiveSyncTimer.Interval = 10000;
m_ActiveSyncTimer.Enabled = true;

rs.RunActiveSyncConnection();


void ActiveSyncTimerEventProcessor(Object myObject, EventArgs myEventArgs)
{
//maybe kill repllog.exe???
//MyProcess mp = new MyProcess();
//if (mp.FindProcess("repllog.exe"))
// mp.KillProcess("repllog.exe");


RegistryKey rk = Registry.CurrentUser;
using (RegistryKey rk1 = rk.OpenSubKey("\\ControlPanel\\Comm", true))
{
rk1.SetValue("AutoCnct", m_iOldValue1);
rk1.SetValue("Cnct", m_sOldValue2);
rk1.Close();
}
rk.Close();

}
----------------------From Attched RasPhoneEntry.cs------------------

public Byte[] byteDevCfgCOM1 = {
0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x10,0x03,0x00,0x00,0x00,0xC2,0x01,0x00,
....
}


//step 1: On device, Start->Settings->Control Panel. Choose "Network and Dial-up Connections". Click "Make New Connections".
//Input "com2", "Direct","Cable on COM2:". Click "Configure", set "115200" etc. "Finish"
///
///
//step 2: Use following code to read manual created ras phone entry: PC-115K for COM1 and com2 for COM2.
///
/// GenerateRasEntryFile
///

public void GenerateRasEntryFile()
{
RegistryKey rk = Registry.CurrentUser;
StreamWriter sw = new StreamWriter("\\ras.txt");
using (RegistryKey rk1 = rk.CreateSubKey("\\Comm\\RasBook\\PC-115K"))
{
sw.WriteLine("");
sw.WriteLine("//\\Comm\\RasBook\\PC-115K");
sw.WriteLine("//1. DevCfg");

sw.WriteLine("Byte[] m_byteDevCfg = {");
Byte[] DevCfg = (Byte[])rk1.GetValue("DevCfg");
int i = 1;
foreach (Byte b in DevCfg)
{
if (i != 8)
{
sw.Write("0x" + b.ToString("X2"));
sw.Write(",");
i++;
}
else
{
sw.WriteLine("0x" + b.ToString("X2") + ",");
i = 1;
}
}
sw.WriteLine("};");
sw.WriteLine("");
sw.WriteLine("");
i = 1;

sw.WriteLine("//2. Entry");
sw.WriteLine("Byte[] m_byteEntry = {");
Byte[] Entry = (Byte[])rk1.GetValue("Entry");
foreach (Byte b in Entry)
{
if (i != 8)
{
sw.Write("0x" + b.ToString("X2"));
sw.Write(",");
i++;
}
else
{
sw.WriteLine("0x" + b.ToString("X2") + ",");
i = 1;
}
}
sw.WriteLine("};");
rk1.Close();
}
using (RegistryKey rk1 = rk.CreateSubKey("\\Comm\\RasBook\\com2"))
{
sw.WriteLine("");
sw.WriteLine("//\\Comm\\RasBook\\com2");
sw.WriteLine("//1. DevCfg");
sw.WriteLine("Byte[] m_byteDevCfg = {");
Byte[] DevCfg = (Byte[])rk1.GetValue("DevCfg");
int i = 1;
sw.WriteLine("1. DevCfg");
foreach (Byte b in DevCfg)
{
if (i != 8)
{
sw.Write("0x" + b.ToString("X2"));
sw.Write(",");
i++;
}
else
{
sw.WriteLine("0x" + b.ToString("X2") + ",");
i = 1;
}
}
sw.WriteLine("};");
sw.WriteLine("");
sw.WriteLine("");
sw.WriteLine("//2. Entry");
i = 1;
sw.WriteLine("Byte[] m_byteEntry = {");
Byte[] Entry = (Byte[])rk1.GetValue("Entry");
foreach (Byte b in Entry)
{
if (i != 8)
{
sw.Write("0x" + b.ToString("X2"));
sw.Write(",");
i++;
}
else
{
sw.WriteLine("0x" + b.ToString("X2") + ",");
i = 1;
}
}
sw.WriteLine("};");
sw.Close();
rk1.Close();
}
}

//step 3: Based on the entry file: ras.txt to create your own Bluetooth ras phone entry with baud rate 115200 and COM1 or 2.
//Why need this: because I can create ras entry using RasGetEntryProperties,RasSetEntryProperties,RasSetEntryDialParams, but it is very hard to
//set baud rate to 115200.
///
/// CreateRasEntry: create your own Bluetooth ras phone entry with baud rate 115200 and COM1 or 2.
///

///
param>
///
///
///
public void CreateRasEntry(string sNewRasEntryName, int iPort, ref int iOldValue1, ref string sOldValue2)
{
RegistryKey rk = Registry.CurrentUser;
using (RegistryKey rk2 = rk.CreateSubKey("\\Comm\\RasBook\\" + sNewRasEntryName))
{
RASPHONEENTRY rs = new RASPHONEENTRY();
if (iPort == 1)
{
rk2.SetValue("DevCfg", rs.byteDevCfgCOM1);
rk2.SetValue("Entry", rs.byteEntryCOM1);
}
else
{
rk2.SetValue("DevCfg", rs.byteDevCfgCOM2);
rk2.SetValue("Entry", rs.byteEntryCOM2);
}
rk2.Close();
}

using (RegistryKey rk1 = rk.CreateSubKey("\\ControlPanel\\Comm"))
{
iOldValue1 = (int)rk1.GetValue("AutoCnct");
rk1.SetValue("AutoCnct", 1);
sOldValue2 = (string)rk1.GetValue("Cnct");
rk1.SetValue("Cnct", sNewRasEntryName); //need to use this specially already created Bluetooth to connect
rk1.Close();
}
rk.Close();

rk = Registry.LocalMachine;
using (RegistryKey rk1 = rk.CreateSubKey("\\ExtModems\\bluetooth_syn"))
{
rk1.SetValue("port", iPort); //might be 2
rk1.Close();
}
rk.Close();
}

//step 4: run repllog.exe to start active connection
///
/// Run ActiveSync Connection
///

public void RunActiveSyncConnection()
{
//run repllog.exe
//ProcessStartInfo psi = new ProcessStartInfo("\\Windows\\repllog.exe","");
//Process.Start(psi);
Functions f = new Functions();
f.OpenExternalProgram("repllog.exe", "AppRunAtRs232Detect"); //activesync auto start when detects serial port connection
}
----------------------From Attched RasConnection.cs------------------

public enum RasFieldSizeConstants
{
RAS_MaxDeviceType = 16,
RAS_MaxPhoneNumber = 128,
RAS_MaxIpAddress = 15,
RAS_MaxIpxAddress = 21,
RAS_MaxEntryName = 20,
RAS_MaxDeviceName = 128,
RAS_MaxCallbackNumber = 48,
RAS_MaxParamKey = 32,
RAS_MaxParamValue = 128,

RAS_MaxAreaCode = 10,
RAS_MaxPadType = 32,
RAS_MaxX25Address = 200,
RAS_MaxFacilities = 200,
RAS_MaxUserData = 200,
RAS_MaxReplyMessage = 1024,
RAS_MaxDnsSuffix = 256,

MAX_PATH = 260,

UNLEN = 256,
PWLEN = 256,
DNLEN = 15
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct RASIPADDR
{
byte a;
byte b;
byte c;
byte d;
}

//Public Enum RasEntryOptions
// RASEO_UseCountryAndAreaCodes = &H1
// RASEO_SpecificIpAddr = &H2
// RASEO_SpecificNameServers = &H4
// RASEO_IpHeaderCompression = &H8
// RASEO_RemoteDefaultGateway = &H10
// RASEO_DisableLcpExtensions = &H20
// RASEO_TerminalBeforeDial = &H40
// RASEO_TerminalAfterDial = &H80
// RASEO_ModemLights = &H100
// RASEO_SwCompression = &H200
// RASEO_RequireEncryptedPw = &H400
// RASEO_RequireMsEncryptedPw = &H800
// RASEO_RequireDataEncryption = &H1000
// RASEO_NetworkLogon = &H2000
// RASEO_UseLogonCredentials = &H4000
// RASEO_PromoteAlternates = &H8000
// RASEO_SecureLocalFiles = &H10000
// RASEO_RequireEAP = &H20000
// RASEO_RequirePAP = &H40000
// RASEO_RequireSPAP = &H80000
// RASEO_Custom = &H100000
// RASEO_PreviewPhoneNumber = &H200000
// RASEO_SharedPhoneNumbers = &H800000
// RASEO_PreviewUserPw = &H1000000
// RASEO_PreviewDomain = &H2000000
// RASEO_ShowDialingProgress = &H4000000
// RASEO_RequireCHAP = &H8000000
// RASEO_RequireMsCHAP = &H10000000
// RASEO_RequireMsCHAP2 = &H20000000
// RASEO_RequireW95MSCHAP = &H40000000
// RASEO_CustomScript = &H80000000
// End Enum

///* RASENTRY 'dwfNetProtocols' bit flags. (session negotiated protocols)
//*/
//#define RASNP_NetBEUI 0x00000001 // Negotiate NetBEUI
//#define RASNP_Ipx 0x00000002 // Negotiate IPX
//#define RASNP_Ip 0x00000004 // Negotiate TCP/IP


///* RASENTRY 'dwFramingProtocols' (framing protocols used by the server)
//*/
//#define RASFP_Ppp 0x00000001 // Point-to-Point Protocol (PPP)
//#define RASFP_Slip 0x00000002 // Serial Line Internet Protocol (SLIP)
//#define RASFP_Ras 0x00000004 // Microsoft proprietary protocol


///* RASENTRY 'szDeviceType' strings
//*/
//#define RASDT_Direct TEXT("direct") // Direct Connect (WINCE Extension)
//#define RASDT_Modem TEXT("modem") // Modem
//#define RASDT_Isdn TEXT("isdn") // ISDN
//#define RASDT_X25 TEXT("x25") // X.25
//#define RASDT_Vpn TEXT("vpn") // PPTP
//#define RASDT_PPPoE TEXT("PPPoE") // PPPoE


//http://msdn.microsoft.com/en-us/library/aa920252.aspx
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct RASENTRY
{
public int dwSize;
public int dwfOptions;
//
// Location/phone number.
//
public int dwCountryID;
public int dwCountryCode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RasFieldSizeConstants.RAS_MaxAreaCode + 1)]
public string szAreaCode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RasFieldSizeConstants.RAS_MaxPhoneNumber + 1)]
public string szLocalPhoneNumber;
public int dwAlternateOffset;
//
// PPP/Ip
//
public RASIPADDR ipaddr;
public RASIPADDR ipaddrDns;
public RASIPADDR ipaddrDnsAlt;
public RASIPADDR ipaddrWins;
public RASIPADDR ipaddrWinsAlt;
//
// Framing
//
public int dwFrameSize;
public int dwfNetProtocols;
public int dwFramingProtocol;
//
// Scripting
//
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]//MAX_PATH
public string szScript;
//
// AutoDial
//
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]//MAX_PATH
public string szAutodialDll;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]//MAX_PATH
public string szAutodialFunc;
//
// Device
//
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RasFieldSizeConstants.RAS_MaxDeviceType + 1)]
public string szDeviceType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RasFieldSizeConstants.RAS_MaxDeviceName + 1)]
public string szDeviceName;
//
// X.25
//
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RasFieldSizeConstants.RAS_MaxPadType + 1)]
public string szX25PadType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RasFieldSizeConstants.RAS_MaxX25Address + 1)]
public string szX25Address;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RasFieldSizeConstants.RAS_MaxFacilities + 1)]
public string szX25Facilities;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RasFieldSizeConstants.RAS_MaxUserData + 1)]
public string szX25UserData;
public int dwChannels;
//
// Reserved
//
public int dwReserved1;
public int dwReserved2;

//it is winCE500 dx
public int dwCustomAuthKey;

}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct RASDIALPARAMS
{
public int dwSize;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RasFieldSizeConstants.RAS_MaxEntryName + 1)]
public string szEntryName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RasFieldSizeConstants.RAS_MaxPhoneNumber + 1)]
public string szPhoneNumber;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RasFieldSizeConstants.RAS_MaxCallbackNumber + 1)]
public string szCallbackNumber;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RasFieldSizeConstants.UNLEN + 1)]
public string szUserName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RasFieldSizeConstants.PWLEN + 1)]
public string szPassword;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (int)RasFieldSizeConstants.DNLEN + 1)]
public string szDomain;
//public uint dwSubEntry; //no need for WinCE
//public IntPtr dwCallbackId; //no need for WinCE
}

class RasConnection
{

[DllImport("coredll.dll", CharSet = CharSet.Auto)]
static extern uint RasDial(
[In]RASDIALEXTENSIONS lpRasDialExtensions,
[In]string lpszPhonebook,
[In]RASDIALPARAMS lpRasDialParams,
uint dwNotifierType,
Delegate lpvNotifier,
ref IntPtr lphRasConn);

//[DllImport("coredll.dll")]
//public static extern uint RasDial(IntPtr dialExtensions, IntPtr
//phoneBookPath, IntPtr rasDialParam, uint NotifierType,
//IntPtr notifier, ref IntPtr pRasConn);

[DllImport("coredll.dll")]
public static extern uint RasHangUp(IntPtr pRasConn);

[DllImport("coredll.dll")]
public static extern uint RasGetEntryProperties(string
lpszPhoneBook, string szEntry, ref RASENTRY lpEntry, ref int dwsize,
char[] lpb, ref uint lpdwSize);

//public static extern uint RasGetEntryProperties(string
//lpszPhoneBook, string szEntry, ref RASENTRY lpEntry, ref int dwsize,
//int lpbDeviceInfo, int lpdwSize);

[DllImport("coredll.dll")]
public static extern uint RasSetEntryProperties(string
lpszPhoneBook, string szEntry, ref RASENTRY lpEntry, int dwEntrySize,
char[] lpb, int dwSize);

[DllImport("coredll.dll")]
public static extern uint RasSetEntryDialParams(string
lpszPhoneBook, ref RASDIALPARAMS lpRasDialParams, bool
fRemovePassword);

[DllImport("coredll.dll", SetLastError = true)]
public static extern uint RasGetEntryDialParams(
string lpszPhonebook,
[In, Out] ref RASDIALPARAMS lprasdialparams,
out bool lpfPassword);
//[DllImport("coredll.dll")]
//public static extern uint RasSetEntryDialParams(string
//lpszPhoneBook, ref RASDIALPARAMS lpRasDialParams, bool
//fRemovePassword);


[StructLayout(LayoutKind.Sequential)]
internal class RasEapInfo
{
public Int32 dwSize = Marshal.SizeOf(typeof(RasEapInfo));
public Byte[] pbEapInfo = null;
}

[StructLayout(LayoutKind.Sequential)]
internal class RASDIALEXTENSIONS
{
public readonly int dwSize = Marshal.SizeOf(typeof(RASDIALEXTENSIONS));
public uint dwfOptions = 0;
public int hwndParent = 0;
public int reserved = 0;
public int reserved1 = 0;
public RasEapInfo RasEapInfo = new RasEapInfo();
}
//public void Connect()
//{
// // Define the dial parameters
// RasDialParams parms = new RasDialParams();
// parms.szDomain = this.Domain;
// parms.szUserName = this.UserName;
// parms.szPassword = this.Password;
// parms.szEntryName = this.PhonebookEntry;

// System.UInt32 retVal =
// RasDial(null, null, dialParms, 0, null, ref RasConnectionHandle);
//}
}

Thursday, September 4, 2008

Window CE, how to get File size, version information in C#?

For file size, length, last write etc, you can use FileInfo as following:

FileInfo aa = new FileInfo("\\xxx");
aa.LastWriteTime;
aa.Length;
aa.CreationTime;

for file version, you have to use some C++ help here:

public class FileVersionInfo
{
#region Variables

private string m_sFileName;
private byte[] m_bytVersionInfo;

#endregion

#region Constants

private const int GMEM_FIXED = 0x0000;
private const int LMEM_ZEROINIT = 0x0040;
private const int LPTR = (GMEM_FIXED | LMEM_ZEROINIT);

#endregion

#region Constructors

///
/// Constructor.
///

/// File name and path.
private FileVersionInfo(string sFileName)
{
if (File.Exists(sFileName))
{
int iHandle = 0;
int iLength = 0;
int iFixedLength= 0;
IntPtr ipFixedBuffer = IntPtr.Zero;

// Get the file information.
m_sFileName = Path.GetFileName(sFileName);
iLength = GetFileVersionInfoSize(sFileName, ref iHandle);

if(iLength > 0)
{
// Allocate memory.
IntPtr ipBuffer = AllocHGlobal(iLength);

// Get the version information.
if(GetFileVersionInfo(sFileName, iHandle, iLength, ipBuffer))
{
// Get language independant version info.
if(VerQueryValue(ipBuffer, "\\", ref ipFixedBuffer, ref iFixedLength))
{
// Copy information to array.
m_bytVersionInfo = new byte[iFixedLength];
Marshal.Copy(ipFixedBuffer, m_bytVersionInfo, 0, iFixedLength);
}
}

// Free memory.
FreeHGlobal(ipBuffer);
}
}
else
{
m_bytVersionInfo = new byte[200];
}
}

#endregion

#region Properties

///
/// Get the file build part.
///

public int FileBuildPart
{
get
{
return Convert.ToInt32(BitConverter.ToInt16(m_bytVersionInfo, 14));
}
}

///
/// Get the file major part.
///

public int FileMajorPart
{
get
{
return Convert.ToInt32(BitConverter.ToInt16(m_bytVersionInfo, 10));
}
}

///
/// Get the file minor part.
///

public int FileMinorPart
{
get
{
return Convert.ToInt32(BitConverter.ToInt16(m_bytVersionInfo, 8));
}
}

///
/// Get the name of the file.
///

public string FileName
{
get
{
return m_sFileName;
}
}

///
/// Get the file private part.
///

public int FilePrivatePart
{
get
{
return Convert.ToInt32(BitConverter.ToInt16(m_bytVersionInfo, 12));
}
}

///
/// Get the product build part.
///

public int ProductBuildPart
{
get
{
return Convert.ToInt32(BitConverter.ToInt16(m_bytVersionInfo, 22));
}
}

///
/// Get the product major part.
///

public int ProductMajorPart
{
get
{
return Convert.ToInt32(BitConverter.ToInt16(m_bytVersionInfo, 18));
}
}

///
/// Get the product minor part.
///

public int ProductMinorPart
{
get
{
return Convert.ToInt32(BitConverter.ToInt16(m_bytVersionInfo, 16));
}
}

///
/// Get the product private part.
///

public int ProductPrivatePart
{
get
{
return Convert.ToInt32(BitConverter.ToInt16(m_bytVersionInfo, 20));
}
}

#endregion

#region Functions

///
/// Allocate unmanged memory.
///

/// Length to allocate.
/// IntPtr object.
private static IntPtr AllocHGlobal(int iLength)
{
return LocalAlloc(LPTR, (uint)iLength);
}

///
/// Free allocated memory.
///

/// IntPtr object to free.
private static void FreeHGlobal(IntPtr hGlobal)
{
LocalFree(hGlobal);
}

///
/// Get the file version information.
///

/// File name and path.
/// FileVersionInfo object.
public static FileVersionInfo GetVersionInfo(string sFileName)
{
return new FileVersionInfo(sFileName);
}

#endregion

#region Win32API

[DllImport("coredll", EntryPoint="GetFileVersionInfo", SetLastError=true)]
private static extern bool GetFileVersionInfo(
string filename,
int handle,
int len,
IntPtr buffer);

[DllImport("coredll", EntryPoint="GetFileVersionInfoSize", SetLastError=true)]
private static extern int GetFileVersionInfoSize(
string filename,
ref int handle);

[DllImport("coredll.dll", EntryPoint="LocalAlloc", SetLastError=true)]
private static extern IntPtr LocalAlloc(
uint uFlags,
uint Bytes);

[DllImport("coredll.dll", EntryPoint="LocalFree", SetLastError=true)]
private static extern IntPtr LocalFree(
IntPtr hMem);

[DllImport("coredll", EntryPoint="VerQueryValue", SetLastError=true)]
private static extern bool VerQueryValue(
IntPtr buffer,
string subblock,
ref IntPtr blockbuffer,
ref int len);

#endregion
}
}

Then:

FileVersionInfo fiWindows = FileVersionInfo.GetVersionInfo(@"\Windows\sdcgina.exe");
//MessageBox.Show("1 Window:" + fiWindows.FileMajorPart + "_" + fiWindows.FileMinorPart + "_" + fiWindows.FileBuildPart + "_"
// + fiWindows.ProductMajorPart + "_" + fiWindows.ProductMinorPart + "_" + fiWindows.ProductPrivatePart + "_" + fiWindows.ProductBuildPart
// + "SystemCF:" + fiSystemCF.FileMajorPart + "_" + fiSystemCF.FileMinorPart + "_" + fiSystemCF.FileBuildPart + "_"
// + fiSystemCF.ProductMajorPart + "_" + fiSystemCF.ProductMinorPart + "_" + fiSystemCF.ProductPrivatePart + "_" + fiSystemCF.ProductBuildPart);

Wednesday, May 23, 2007

MessageBox with more options in C#

MessageBox in C# does not provide a lot of options as in C++. Following is the example to add these option back:

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;

namespace XXX
{
public class MessageBoxAdvanced
{
#region WINUSER CONSTS
// From winuser.h
public const uint MB_OK = 0x00000000;
private const uint MB_OKCANCEL = 0x00000001;
private const uint MB_ABORTRETRYIGNORE = 0x00000002;
private const uint MB_YESNOCANCEL = 0x00000003;
public const uint MB_YESNO = 0x00000004;
private const uint MB_RETRYCANCEL = 0x00000005;
private const uint MB_HELP = 0x00004000;

private const uint MB_USERICON = 0x00000080;

private const uint MB_ICONHAND = 0x00000010;
private const uint MB_ICONQUESTION = 0x00000020;
private const uint MB_ICONEXCLAMATION = 0x00000030;
private const uint MB_ICONASTERISK = 0x00000040;
private const uint MB_ICONWARNING = MB_ICONEXCLAMATION;
private const uint MB_ICONERROR = MB_ICONHAND;
private const uint MB_ICONINFORMATION = MB_ICONASTERISK;
private const uint MB_ICONSTOP = MB_ICONHAND;

private const uint MB_DEFBUTTON1 = 0x00000000;
private const uint MB_DEFBUTTON2 = 0x00000100;
private const uint MB_DEFBUTTON3 = 0x00000200;

private const uint MB_RTLREADING = 0x00100000;
private const uint MB_DEFAULT_DESKTOP_ONLY = 0x00020000;
private const uint MB_SERVICE_NOTIFICATION = 0x00200000; // assumes WNT >= 4
private const uint MB_RIGHT = 0x00080000;

public const uint MB_APPLMODAL = 0x00000000;
public const uint MB_SYSTEMMODAL = 0x00001000;
private const uint MB_TASKMODAL = 0x00002000;

public const uint MB_TOPMOST =0x00040000;

// For setting window icon.
private const uint WM_SETICON = 0x00000080;
private const uint ICON_SMALL = 0;
private const uint ICON_BIG = 1;

private const int WH_CBT = 5;

private const int HCBT_CREATEWND = 3;

private const int IDOK = 1;
private const int IDCANCEL = 2;
private const int IDABORT = 3;
private const int IDRETRY = 4;
private const int IDIGNORE = 5;
public const int IDYES = 6;
public const int IDNO = 7;

#endregion

[DllImport("coredll.dll")]
public static extern int MessageBox(int hWnd, String sMessage, String sTitle, uint type);
}
}

* For .Net CF

Error Report Example in C#

public class CreateErrorLog
{
#region Variables
private string m_sLogFormat;
private string m_sErrorTime;
#endregion

#region Properties
//get and set - public access of private members
public string LogFormat
{
get
{
return m_sLogFormat;
}
set
{
m_sLogFormat = value;
}
}
public string ErrorTime
{
get
{
return m_sErrorTime;
}
set
{
m_sErrorTime = value;
}
}
#endregion

#region Constructor
public CreateErrorLog()
{
// TODO: Add constructor logic here
m_sLogFormat = "[2T]"+ DateTime.Now.ToShortDateString().ToString()+" "+DateTime.Now.ToLongTimeString().ToString()+" ==> ";
string sYear = DateTime.Now.Year.ToString();
string sMonth = DateTime.Now.Month.ToString();
string sDay = DateTime.Now.Day.ToString();
m_sErrorTime = sYear+sMonth+sDay;
}
~CreateErrorLog(){}
#endregion

#region Functions
public void ErrorLog(string sPathName, string sErrMsg)
{
StreamWriter sw = File.AppendText(sPathName+m_sErrorTime+".txt");
sw.WriteLine(m_sLogFormat + sErrMsg);
sw.Flush();
sw.Close();
}
#endregion
}

Ascii to Hex in C#

try
{
int iTemp = 0;
string sTemp = "";
string strHex;
foreach (char c in txtKeyA.Text)
{
iTemp = c;
strHex = String.Format("{0:x2}", (uint)System.Convert.ToUInt32(iTemp.ToString()));
// MessageBox.Show(strHex);
sTemp = sTemp + strHex;
}
txtKeyA.Text = sTemp;
this.btnToHex.Enabled = false;
this.btnToAscii.Enabled = true;
}
catch(Exception eE)
{
// MessageBox.Show(eE.ToString());
MessageBox.Show("Failed to convert!!! Please check your input format!");
}

Hex to Ascii Conversion in C#

try
{
int n =0;
string temp;
string temp2 = "";
for(int i = 0; i {
temp = txtKeyA.Text.Substring(i,2);
n = Convert.ToInt32(temp, 16);
//To convert it to a character, simply cast the integer to char
temp2 = temp2 + ((char)n).ToString();
}
txtKeyA.Text = temp2;
this.btnToHex.Enabled = true;
this.btnToAscii.Enabled = false;
}
catch(Exception eE)
{
// MessageBox.Show(eE.ToString());
MessageBox.Show("Failed to convert!!! Please check your input format!");
}