Tuesday, April 17, 2007

Sometimes when trying to connect Visual Studio t a device, especially to a custom CE platform, it is helpful to see if there are any problems reported by the CoreCon components on the device side. CoreCon components (ConmanClient, trasnport DLLs, edbgtl.dll and edm.exe) all have an integrated logging facility, which can be used by a developer for troubleshooting.

To enable Corecon debug log you can set the following under HKLM\Software\Microsoft\VSD\Logging

VSD_LogEnabled: DWORD:1,0

VSD_LogToDebugger: DWORD:1,0

VSD_LogToConsole: DWORD: 1,0

VSD_LogToFile: DWORD:1,0

VSD_LogLevel: DWORD - set to at least 4, up to 9

VSD_LogFile: REG_SZ (default VSDLogFile.txt)

Keep in mind that the ConMan log can be quite chatty, so enable it sparingly and only when needed

4/17/2007 12:12:44 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [0]  | 
 Friday, April 13, 2007

XML-based device configuration is a powerful mechanism of configuring Windows Mobile 2003 and newer devices. There are four ways to provision your device with new settings:

  1. Call DMProcessConfigXML on device. It can be done from native or managed code.
  2. Build a CAB file containing _setup.xml with provisioning XML and run it on the device
  3. Send the xml configuration via WAP push
  4. Use RapiConfig tool shipped with WIndows Mobile SDK (under Tools)

But what if you wanted to perform configuration from your own, PC-based installer? Granted, you could use method 2 and copy the cab over to the device, then invoke wceload etc. Or you could write your own RAPI dll and use CeRapiInvoke. Or perhaps even launch RapiConfig to do this for you. Fortunately there is an easier way. As one could suspect, RapiConfig does not use a complex approach. Rather it benefits from an undocumented but handy RAPI call that is the desktop version of DMProcessConfigXML. It is exported by ordinal (25) and has the same signature as DMProcessConfigXML. Unlike DMProcessConfigXML, the pointer returned by it in the 3rd parameter needs to be freed using CeRapiFreeBuffer.

#pragma comment(lib, "rapi")

STDAPI CeRapiInit();
STDAPI CeRapiUninit();
STDAPI CeRapiFreeBuffer(LPVOID);
typedef HRESULT (__stdcall *CeProcessConfigType)(LPCWSTR pszConfig, DWORD dwFlags, LPCWSTR* ppszConfigOut);

int _tmain(int argc, _TCHAR* argv[])
{
 if ( argc != 3 )
 {
  _tprintf(_T("Usage: rapiconfig <config file> <out file>\n"));
  return 1;
 }

 CeRapiInit();
 
 CeProcessConfigType CeProcessConfig =
   (CeProcessConfigType)GetProcAddress(GetModuleHandle(_T("rapi.dll")), (LPCSTR)25);

 HANDLE hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
 if ( hFile == INVALID_HANDLE_VALUE )
 {
  _tprintf(_T("Unable to open %s\n"), argv[1]);
  goto Exit;
 }

 DWORD cbConfig = GetFileSize(hFile, NULL);
 BYTE* pBuffer = new BYTE[cbConfig];
 if ( !pBuffer )
  goto Exit;

 ReadFile(hFile, pBuffer, cbConfig, &cbConfig, NULL);
 
 LPCWSTR pOut;
 LPWSTR pIn;
 pIn = new WCHAR[cbConfig + 1];
 ZeroMemory(pIn, (cbConfig+1) * 2);
 mbstowcs(pIn, (LPCSTR)pBuffer, cbConfig);
 HRESULT hr;
 if ( FAILED(hr = CeProcessConfig(pIn, 1, &pOut) ))
 {
  _tprintf(_T("Unable to process: %d\n"), hr);
 }

 HANDLE hFileOut = CreateFile(argv[2], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
 if ( hFileOut == INVALID_HANDLE_VALUE )
 {
  _tprintf(_T("Unable to create %s\n"), argv[2]);
  goto Exit;
 }

 WriteFile(hFileOut, pOut, (wcslen(pOut) + 1 )* 2, &cbConfig, NULL);

 CloseHandle(hFileOut);
 CeRapiFreeBuffer((LPVOID)pOut);

Exit:
 if ( hFile != INVALID_HANDLE_VALUE )
  CloseHandle(hFile);

 CeRapiUninit();
 return 0;
}

 

4/13/2007 5:43:46 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [0]  | 
 Sunday, February 25, 2007

Raffaele Rialdi pointed out that attempting to run RTF Host from Compact Framework 3.5 Power Toys on an emulator produces the following error:

This is caused by RTF getting confused because the default CoreCon transport on the emulator is DMA (DeviceDMA.dll). Here are the steps to add emulator as a manual Tcp connection. Not that many will need it, but it is useful for a demo

1. Start Emulator using Device Emulator Manager.
2. Configure Network and Storage card folder
3. Copy to storage card folder the following file: "C:\Program Files\Common
Files\microsoft shared\CoreCon\1.0\Target\wce400\armv4i\TCPConnectionA.dll"
4. In File ExplorerNavigate to \Windows\Corecon1.1. If you don't see it
there, connect to the emulator from Studio
5. Launch ClientShutdown (you should see a guid-named folder to appear)
6. Copy \Storage Card\TcpConnectionA.dll to \Windows
7. Go to \Windows and delete DeviceDMA.dll (if you can't, you forgot to
launch ClientShutdown)
8. Go back to \Windows\Corecon1.1 and launch ConmanClient.exe
9. Launch RTF Host. Enjoy

2/25/2007 6:45:36 AM (Pacific Standard Time, UTC-08:00)  #    Comments [0]  | 

Raffaele Rialdi has pointed out that trying to run RTF Host from CF 3.5 Power Toys (required for manual connectivity) on a Windows Mobile emulator produces an error :

This is caused by RTF getting confused and trying to use DMA transport instead of TCP. Here are the steps to establish a manual RTF connection to an emulator (you don't really need it unless you are doing a demo)

1. Start Emulator using Device Emulator Manager.

2. Configure Network and Storage card folder

3. Copy to storage card folder the following file: "C:\Program Files\Common
Files\microsoft shared\CoreCon\1.0\Target\wce400\armv4i\TCPConnectionA.dll"

4. In File ExplorerNavigate to \Windows\Corecon1.1. If you don't see it
there, connect to the emulator from Studio

5. Launch ClientShutdown (you should see a guid-named folder to appear)

6. Copy \Storage Card\TcpConnectionA.dll to \Windows

7. Go to \Windows and delete DeviceDMA.dll (if you can't, you forgot to
launch ClientShutdown)

8. Go back to \Windows\Corecon1.1 and launch ConmanClient.exe

9. Launch RTF Host. Enjoy

2/25/2007 4:55:18 AM (Pacific Standard Time, UTC-08:00)  #    Comments [0]  | 
 Sunday, February 04, 2007

 Over the weekend actor Ryan O'Neal has been arrested on assault charges
(allegedly assaulted his son, Griffin O'Neal)
(The news article is here)

From TFA:

    Ryan O'Neal's film credits include "Love Story," "Paper Moon," "Green
Ice" and "Barry Lyndon."

and further

    Griffin O'Neal appeared in a number of B-movies, including "The Assault
of the Killer Bimbos
."

I have to say that father's movie career impresses me somewhat more. I think
under circumstances I would have slapped my offspring a few times too...

2/4/2007 10:18:21 PM (Pacific Standard Time, UTC-08:00)  #    Comments [0]  | 
 Thursday, December 07, 2006

I came across this picture while reading fark.com. It fairly well reflects my feelings about ... many things that happen in everyday life while working with people, companies, service providers etc.

 

12/7/2006 2:34:46 PM (Pacific Standard Time, UTC-08:00)  #    Comments [0]  | 
 Monday, October 02, 2006

I have a lot of respect for MSDN technical articles. They are more often than not a source of knowledge one would be hard pressed to obtain from official documentation. Kraig Brockschmidt's treatise on OLE internals, Nancy Winnick Clutz explanation of TAPI, Icon internals by John Hornick - all of these are precious gems of knowledge. Heck, I even wrote a few myself. Over the years there were some that are brilliant and concise, other that were less interesting. Almost every article there had some code posted with it. The code samples would also vary in quality, but not so much as to raise an eyebrow.

On several occasions I had this conversation with my teenage daughter, the gist of which was that even though the Algebra lesson is not an English lesson, it does not mean she can disregard the grammar completely, while doing her math homework. Apparently it was not obvious to her, that writing properly is not something you do only when you absolutely have to. Similarly, I suppose when you write code, even throwaway code, you should still be conscious of how you do it.

When I first came across this, my first reaction was - this is good stuff. It'll teach developers not to use an old, outdated control and show, how to replace it with alternative modern controls. And then I saw the following gem:

If you must search compiled code, you can look certain patterns that represent the GUIDs. For example, the following GUID:

{ABCDEFGH-IJKL-MNOP-QRST-UVWXYZ012345}

becomes the following hexadecimal sequence in binary:

GH EF CD AB KL IJ OP MN QR ST UV WX YZ 01 23 45

 

Er, what hexadecimal sequence?
But following it was a code sample

// Compile and execute:  "FindGUIDs YourApplication.exe"
using System;
using System.Text;
using System.IO;

namespace FindGUIDs {
class Program {
  static void Main(string[] args) {
    FileStream    fs = File.OpenRead(args[0]);
    StringBuilder sb = new StringBuilder();
    do {
      Int32 b = fs.ReadByte();
      if (-1 == b) {
        break;
      }
      sb.AppendFormat("{0:X2}", b);
    } while (true);
    fs.Close();
    String s = sb.ToString();
    if (s.Contains("E0A58D4371F1D011984E0000F80270F8"))
      Console.Out.WriteLine("GUID for TriEditDocument Class detected.");
    if (s.Contains("DFA58D4371F1D011984E0000F80270F8")) {
      Console.Out.WriteLine(
        "GUID for ITriEditDocument Interface detected.");
      }
      if (s.Contains("0002362DF5FFd1118D0300A0C959BC0A")) {
        Console.Out.WriteLine("GUID for DHTMLEdit Class detected.");
      }
      if (s.Contains("91B504CE1F2Bd2118D1E00A0C959BC0A")) {
        Console.Out.WriteLine("GUID for IDHTMLEdit Interface detected.");
      }
    }
  }
}

Basically, what's happening here is that the application is trying to find occurences of a GUID in a binary file. I've seen many approaches to searching a binary string in a file. Some were simpler to implement, the other are more efficient, but harder to understand. This one takes the cake. In a nutshell, this code reads a binary file, byte by byte, and converts each byte into its string hexadecimal represenation. Then this string is appended to a StringBuilder. Once the entire file is loaded into StringBuilder (consuming filesize * 4 bytes of memory), the StringBuilder is used to produce a string (another memory allocation of the same size edited: no, this is actually done in place. Thanks, Dunkan!) and the string is being searched for a GUID substring.

I won't even go into the efficiency of string search as used above. My point is that you either do things right, or you sidestep the whole issue by not providing the code sample (not really needed in the context of this article) and leaving it as an excercise for the reader.

Some screens later in the article we find the following gem of regular expression (JScript, searching an HTML document for tag):

var rex = new RegExp("]*>", "i");

Er, what happened to the non-greedy qualifiers? What is that \s doing inside []? This feels like something written by a person, who does not use javascript day-to-day.

Please, please let's keep MSDN technical library standards high. After all we all benefit from better written code.

10/2/2006 1:23:53 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [3]  | 
 Thursday, September 28, 2006

Several people have hit a problem while installing the service pack on Windows Server 2003 machines. The installation (that takes obscenely long time) eventually fails with a message:

Error 1718: The file xxxxxxxx.msp was rejected by digital signature policy.

Two things with repsect to that:

1) I had this problem and was eventually able to complete installation (on the second try). What has changed is that I moved the SP file from a network location to a local drive.

2) Take a look at the setup log. It can be found under %temp%\VS80sp1-KB918525-X86-Beta-ENU (this path can be pasted into Run box to open the folder)

9/28/2006 2:08:37 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [0]  | 
 Friday, September 15, 2006

It's been pointed out quite a few times how Google AdSense sometimes produces the results that are not exactly what was intended. But the Google is not the only one that suffers from this. Here is a screen scrap of a new article that tells about a not-so-bright Tennessee town mayor who unknowingly agreed to shooting a scene of a movie called Thong Girl 3 in his office. I mean I understand he might not have read the script, but what about the title???

Anyway, the good part is actually the ad inside the article.

9/15/2006 3:42:16 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [0]  |