Welcome to MSDN Blogs Sign in | Join | Help

Recommended China IT Web Links

Like anyone who is looking to ride the wave of China's booming economy, I always want to know what are the hot topics and technological trends in its mobile wireless industry and IT industry. Below is a list of links I use to keep me updated.

http://www.cctime.com 飞象网 3G, cell phone, mobile operators, created by Xiang Ligang (blog).

http://blog.sina.com.cn/lm/tech/ 新浪IT博客 tech blogs at sina.com

http://cn.engadget.com engadget中文版 engadget Chinese site

Please feel free to share links you want to recommend.

Posted by zhengpei | 0 Comments
Filed under:

Mobile 2.0 - Crtical Issues and Why Japan and Korea are the Mobile Time Machines

I came across a great presentation deck on "Mobile 2.0" written by  Gerhard Fasol, CEO of Eurotechnology Japan K. K. In the presentation, Gerhard shared his insight into next generation mobile services and four critical issues, Platforms, Business Models, Globalization, and Standardization vs Risk Taking & Early Adoption. Definitely worth a read.

The presentation also has some interesting data showing Japan and Korea being the "Mobile Time Machines" - they are way ahead of EU (and US) in adopting new technologies and business models. Speaking of my personal experience, in Tokyo I saw people use cell phone at the gate to enter train stations. I don't know if people can do the same anywhere in the US.

Source: Eurotechnology.com 

 

Posted by zhengpei | 0 Comments
Filed under:

Best Client Apps of Twitter, Facebook, LinkedIn, Youtube, Picassa for Windows Mobile

Here is the outcome of my little research... 

Best Twitter Client for Windows Mobile

PocketTwit

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

Best Facebook Client for Windows Mobile

Offical Facebook Client by Microsoft

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

Best LinkedIn Client for Windows Mobile

There is no LinkedIn client for Windows Mobile yet at this moment.

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

Best Youtube Client for Windows Mobile

The official Youtube client

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

Best Picasa Client for Windows Mobile

No standalone app available yet. From a web browser you can visit m.google.com/photos to acccess the mobile picasa site.

Twitter-Fanfou, Omegle-LuGuoDe, and ppstream ...

Twitter: Fanfou (饭否)

Omegle: Luguode (路过的)

LinkedIn: Wealink

Facebook: KaiXin (开心)

For every popular social networking site in the US, several Chinese copycats have been created--the idea was adopted, but the business model and user experience are often totally different.

Keep in mind that Chinese people are quite open and willing to chat/comment in online forums or using SMS. According to data published by China Mobile and China Unicom, every Chinese cell phone user sent more than 850 text messages on average in 2008. The need for communication with close friends, with people in the same industry, and with whoever wants to chat is evident. Those copycats (山寨) above were created by those entrepreneurs who see the huge opportunity of capitalizing on the localized Chinese social networking service market. Will they succeed? Hard to say, depending on how good the localization is done, how to build a hype(?) for the site, and perhaps how to convince a Internet giant to acquire it......


On the other hand, there are very cool home-grown Chinese online services and also financially successful. Some examples are ppstream, xunlei, and of course, QQ. Their US competitors (if any) are nowhere close to them by all means. 

With 3G services launched in China, and upcoming iPhone and oPhone launches, a new battlefield is emerging.

Posted by zhengpei | 1 Comments
Filed under:

Remote-Desktop into MacOS from Windows Mobile

Windows Mobile 6 has the built-in remote desktop client. So you can use it to remote desktop into any Windows machine running terminal services (i.e., running the RDP service that listens at Port 3389). For example, once you enable remote desktop on your XP box, you can remote into it using the client on Windows Mobile. For any other platforms, as long as you have the open source xrdp package installed (which is a RDP server),  you can remote into it.

RDP is only one flavor of the remote-desktop world. VNC (Virtual Networking Computing) has been there way before RDP becomes pupular on Windows.

For MacOS, there is an easier way to remote-desktop into it:

  1. Enable Apple Remote Desktop (an implementation of VNC service): Preferences > Sharing > select Apple Remote Desktop
  2. Install a VNC client on your Windows Mobile device. I tried several, but only ZoomVNC works on my WM6.1 device. 
Done. Isn't that simple?
Posted by zhengpei | 3 Comments
Filed under:

Verifying If a File has Been Signed By a Specific Certificate in Device Cert Store

Is there a quick way to decide if a file has been signed by a specific certificate?  This is definitely part of Windows Mobile code, but it seems there is no easy-to-use APIs for this task. I spent some time investigating this using Windows Mobile AKU and the SDK. Here is my way of doing this:
 
1. Use CertFindCertificateInStore(seen in wincrypt.h in SDK) to find the certificate you want to use to verify a file; This function returns a PCCERT_CONTEXT.

2. Use MinCryptVerifySignedFileEx(seen in mincrypt.h in AKU) to verify a file is indeed signed by that certificate; The way this API verifies the file is trying to root chain the certficiate used to sign the file, following the certificate path to look for a root certficiate in the specified store.

Let's say we want to check if file my.dll is signed by a self-issued certificate called mycert, which is in the device's privileged certificate store. Now, we open the cert store, find our that certificate using the cert’s SHA-1 hash (or subject, etc), and use it to call MinCryptVerifySignedFileEx() to verify. If my.dll is signed by mycert, or is signed by a code signing certificate issued by the issuer of mycert, then the API return TRUE, meaning that my.dll is indeed signed and should be 'trusted'.

The core part of this who thing is this:

    DWORD CheckBinary(LPWSTR lpwsFileName, PCCERT_CONTEXT pDesiredCert)
    {
        DWORD dwRet;
        MINCRYPT_TRUST_INFO _trust = {0};   // Used by MinCryptVerifySignedFileEx, details see mincrypt.h
        MINCRYPT_ROOT_CERT _rootcert;       // Used by MinCryptVerifySignedFileEx
        MINCRYPT_TRUST_STATUS _trust_status = {0};

        _trust.version = MINCRYPT_TRUST_INFO_VER;
        _trust.flags   = 0;
        _trust.cRootCerts = 1;              // number of root certs in pRootCerts array
        _trust.cRevocationList = 0;         // number of entries in revocation list
        _trust.pRootCerts = &_rootcert;

        BYTE* pPubKey = pDesiredCert->pbCertEncoded;
        PCRYPT_DER_BLOB prgCertBlob = _rootcert.rgCertBlob;
        dwRet = MinAsn1ParseCertificate(pPubKey, pDesiredCert->cbCertEncoded, prgCertBlob);
        if(dwRet < 0)
        {
            wprintf(L"Error parsing the certificate!\n");
            return -1;
        }
        dwRet = MinCryptVerifySignedFileEx(
            MINCRYPT_FILE_NAME,
            lpwsFileName,
            &_trust,
            &_trust_status,
            0,
            0,
            0,
            0
            );
        if(dwRet != ERROR_SUCCESS)
        {
            //Error code can be found here: http://blogs.msdn.com/eldar/archive/2007/04/03/a-lot-of-hresult-codes.aspx
            //Or use VS error lookup tool
            //Note, if error is 6, then file not found.
            wprintf(L"The file %s was not certified by our cert!: Error: %x\n", lpwsFileName, dwRet);
        }
        else
        {
            wprintf(L"The file %s was certified by our cert!\n", lpwsFileName);
        }
        return dwRet;
    }

Note: In visual studio, you need to add paths to those headers and libs (crypto32.lib, mincrypt.lib, and rsaenh.lib are all in AKU common OAK lib directory). 
Posted by zhengpei | 1 Comments

Chinese Input Method on English Windows Mobile Devices

My Windows Mobile devices usually run WWE (World Wide English). To view Chinese on the device I download and install http://cid-8a0406089aad8752.skydrive.live.com/self.aspx/Shared/Yahei.cab

Then the question is how to input Chinese as I bring to my devices to China quite often and I need to send SMS in Chinese. Well, as you know there is CE-Star but it is not free. Good news is there is a pretty good FREE Chinese input method for Windows Mobile: Dayhand Input Method (点迅).

 

Update: font link updated.

Posted by zhengpei | 2 Comments

Mobile OS Virtualization

Even before VMWare acquires Trango, the French company specialized in mobile OS virtualization, I've heard some OEMs in talks with Trango for future Windows Mobile devices.

A picture is better than 1000 words. Here is a picture of Trango's virtual processor:

The hypervisor is the Virtual Machine Monitor. From Trango's website:

The TRANGO hypervisor is a virtualization layer that allows multiple Virtual Machines to run on a single Hardware platform. It is based on paravirtualization technology which requires that the guest OS be slightly modified.  "Privileged" or kernel mode instructions in the OS that access hardware directly are modified to API calls to the hypervisor, or "hypercalls".

Para virtualization is the most appropriate virtualization technique for embedded applications as it allows the best real-time performance compared to emulation or full virtualization which impose considerable resource burdens on the system both from the standpoint of memory and CPU overhead.

This is like Microsoft's Hypervisor for desktop systems, as opposed to VMWare's. This solution can be used for enabling something that Windows Mobile does not support, for example, iMode for Japanese market, or maybe running Windows Mobile apps on iPhone, or the other way around?

Posted by zhengpei | 1 Comments
Filed under:

Cellular Based Video Telephony on Windows Mobile

How do you enable Video Telephony on Windows Mobile? What are the things you have to be careful of?

First of all, what is the underlying bearer? WiFi, WiMax, or 3G? For WiFi and WiMax, VT will be just a Video over IP application. For 3G, however, most likely it will be a circuit-switching based application. This article is focused on the 3G side of video telephony on Windows Mobile. The standard 3G-324M is based on ITU H.324 standard that specified a data rate of 64 kilobits per second over a circuit-switched UMTS or TD-SCDMA connection.

The following picture shows the 3G-324M architecture (copied from an article published at www.smartphonemag.com):
Overall, to enable Video Telephony on Windows Mobile, there are four major work items to be done:
  1. Develop a VT application must enable circuit switching for video call with the baseband processor using TAPI;
  2. Must have 3G-324M protocol stack, such as the one from Radvision or Dilithium;
  3. Must have Video codecs for H.264 (a.k.a MPEG-4 AVC), H.263, 3gp, etc.
  4. VT application should be tightly integrated with Windows Mobile phone app;
The following picture from Radvision shows the architecture of a VT app on Windows Mobile:


Note that the VT application goes directly to TAPI and then RIL. Contrast to handling cellular voice calls, connection manager is not involved for VT calls. However, connection manager will be able to detect radio resources used by VT calls and manage them as "alien calls" which has a higher priority of data connection but lower priority of cellular voice call.

Phone canvas integration with the VT application is easy - Windows Mobile provides many ways to customize controls on the phone canvas. The AKU has numerous examples of doing that. Outlook and contacts integration can also be done without too much difficulty. Codec-wise, the programming interface is standard Direct Show based.

The major work is the 3G-324M stack, such as implementing call establishment, control control and quality of service support. Doing that from scratch does not seem to worth the effort. Adopting a high-performance stack is a common practice among device manufacturers.
Posted by zhengpei | 1 Comments
Filed under:

Debugging Stack Fault of Hopper Failure on Windows Mobile devices

1.  Introduction

Stack fault happens whenever a thread’s stack is almost used up, and the Windows CE kernel will generate a message of the problem like this:

9381584 PID:47c40bda TID:24ccc7ce [Stack fault]: Thread=85fa3a40 Proc=8060e640 'device.exe'

9381584 PID:47c40bda TID:24ccc7ce AKY=00020013 PC=01a23be0(dummy.dll+0x00003be0) RA=03ed33a0(devmgr.dll+0x000033a0) BVA=24081d24 FSR=00000007

 

The data in the message is important to understand the failure, which can be a data abort, stack fault, page fault, etc.

  • AKY  "Access Key": Process slot bitmask corresponding to the processes the excepting thread has access to. Platform Builder can shows Access Keys of each process in the “Processes” window.
  • PC "Program Counter": Represents the current line of instruction. On ARM platforms, this is the current value of the PC register and EIP (Instruction Pointer) on x86 platforms. If symbols are available, the exception handler will attempt to provide an offset line into the DLL that caused the exception.
  • RA "Return Address": Pointer to the instruction address of the function that called the current function. Had the current function NOT caused an exception, this is where we would return to. For a DLL on Windows CE, simply use the last two bytes of the address plus the preferred load address of the module (0x10000000) to search Rva+Base column in the corresponding map file and you will find the function the address falls into. For an EXE, use the last two bytes of the address plus the preferred load address (0x00010000) to search the Rva+Base column. The same calculation applies to BVA below.
  • BVA "Base Virtual Address": The contents of BVA depend on the type of exception found. If the exception is a Prefetch Abort, the value points directly to the PC register (execution point). If the exception is a Data Abort, then this value points to why the exception was caused. It is a combination of the Virtual Memory base of the module found plus the value that caused the exception.
  • FSR "Fault Status Register": The FSR represents several flags that will help you understand the nature of your exception. For ARM devices the following flags can be set:

#define FSR_ALIGNMENT       0x01

                #define FSR_PAGE_ERROR      0x02

                #define FSR_TRANSLATION     0x05

                #define FSR_DOMAIN_ERROR    0x09

                #define FSR_PERMISSION      0x0D

To confirm a stack fault failure, you should at least have the system dump when the problem occurred. Or better yet, you have a KITL enabled device and you can reproduce the problem.

2.  A Real Example

The following is a real world example of stack fault in while running Hopper with focus on tmail.exe.

9381584 PID:47c40bda TID:24ccc7ce [Stack fault]: Thread=85fa3a40 Proc=8060e640 'device.exe'

9381584 PID:47c40bda TID:24ccc7ce AKY=00020013 PC=01a23be0(dummy.dll+0x00003be0) RA=03ed33a0(devmgr.dll+0x000033a0) BVA=24081d24 FSR=00000007

Failed to initialize bug tagger!

9383377 PID:47c40bda TID:24ccc7ce RaiseException: Thread=85fa3a40 Proc=8060e640 'device.exe'

9383463 PID:47c40bda TID:24ccc7ce AKY=00020013 PC=03f6c3c4(coredll.dll+0x0001e3c4) RA=8030a514(NK.EXE+0x0000a514) BVA=00000001 FSR=00000001

9384183 PID:a79698b2 TID:a5f6ac92 OEMIoControl: Unsupported Code 0x1010058 - device 0x0101 func 22

 

Assembly Dump:

DUM_IOControl:

01A23BA4 E1A0C00D             mov         r12, sp

01A23BA8 E92D5FF0             stmdb       sp!, {r4 - r12, lr}

01A23BAC E28DB028             add         r11, sp, #0x28 <<r11 points back to last sp (0x28 accounts for 40 bytes for those saved registers)

01A23BB0 E59FCD48             ldr         r12, [pc, #0xD48]   << Load value into r12 from address 0x01A24900. Note that the value is negative. (FFFF7EFC or -33028, the size of the local variables)

01A23BB4 E08DD00C             add         sp, sp, r12         <<  Sp = 24081D44 and only 7K (1D44)  left on the stack after this.

$L36859:

01A23BB8 E1A06002             mov         r6, r2

01A23BBC E1A04001             mov         r4, r1

01A23BC0 E59F3D34             ldr         r3, [pc, #0xD34]

01A23BC4 E5933000             ldr         r3, dwLenIni

01A23BC8 E50B302C             str         r3, [r11, #-0x2C]

01A23BCC E59F0D24             ldr         r0, [pc, #0xD24]

01A23BD0 E3A08001             mov         r8, #1

01A23BD4 E3A03000             mov         r3, #0

01A23BD8 E3A07057             mov         r7, #0x57

01A23BDC E24BC902             sub         r12, r11, #2, 18 << r12 = r11 -2>>18 = 0x24081e70

01A23BE0 E50C7114             str         r7, [r12, #-0x114]  << Crash here since a page in request failed due to stack overflow

01A23BE4 E24BC902             sub         r12, r11, #2, 18

01A24900 FFFF7EFC             ???

 

Registers Dump:

 R0 = 01A23138 R1 = 0001000D R2 = 24089F80 R3 = 00000000

 R4 = 0001000D R5 = 0005E180 R6 = 24089F80 R7 = 00000057

 R8 = 00000001 R9 = 24089F80 R10 = 00000000 R11 = 24089E70

 R12 = 24081E70 Sp = 24081D44 Lr = 03ED33A0 Pc = 01A23BE0

 Cpsr = 4000001F

 

 Negative=0 Zero=1 Carry=0 Overflow=0 Q=0

 

Call Stack Dump:

Call Stack: tmail.exe: 0x24CCC7CE  11:36:54 12/07/2007 Taipei Standard Time

    0x24081d44 DUMMY!DUM_IOControl(void * 0x00000000, unsigned long 0x00000000, unsigned long * 0x00000000) dummy.cpp line 491 + 20 bytes

    0x24089e70 DEVMGR!DM_DevDeviceIoControl(void * 0x00000000, unsigned long 0x00000000, unsigned long * 0x00000000, _OVERLAPPED * 0x00000000 {Internal=??? InternalHigh=??? Offset=??? ...}) devfile.c line 464 + 44 bytes

    0x24089eb4 NK!SC_DeviceIoControl(void * 0x00000000, unsigned long 0x0001000d, unsigned long * 0x80321034, _OVERLAPPED * 0x0ba6169c {Internal=0x00550044 InternalHigh=0x0031004d Offset=0x0000003a ...}) kmisc.c line 2860 + 52 bytes

    0x24089f28 COREDLL!xxx_DeviceIoControl(void * 0x00000000, unsigned long 0x00000000, unsigned long * 0x00000000, _OVERLAPPED * 0x00000000 {Internal=??? InternalHigh=??? Offset=??? ...}) twinbase.cpp line 49 + 52 bytes

    0x24089f60 CAMERA_MAINSTONEII!SetCameraPresentFlag() cameradriver.cpp line 419

    0x24089f90 CAMERA_MAINSTONEII!CAM_Open() cameradriver.cpp line 461

    0x24089fb4 DEVMGR!I_CreateDeviceHandle(void * 0x0005e020) devfile.c line 98 + 24 bytes

    0x2408a004 DEVMGR!DM_CreateDeviceHandle() devfile.c line 182 + 24 bytes

    0x2408a084 COREDLL!xxx_CreateDeviceHandle() tdevice.c line 122

    0x2408a08c FILESYS!FS_CreateFileW(unsigned long 0x00075c08, unsigned long 0xc0000000, void * 0x00000001) fsmain.c line 2275 + 28 bytes

    0x2408a5ac COREDLL!xxx_CreateFileW(unsigned long 0x00000003, unsigned long 0x00000080, void * 0x00000000) twinbase.cpp line 100 + 52 bytes

    0x2408a5e0 QUARTZ!CCaptureAdapter::Load() adapter.cpp line 69 + 44 bytes

End Call Stack: tmail.exe: 0x24CCC7CE  11:36:54 12/07/2007 Taipei Standard Time

 

Combining the call stack and the registers, we can draw the following figure of the thread stack:

The local variable size in the function DUM_IOControl() is 33028 (Note that -33298= FFFF7EFC). However, the thread stack is almost used up, with only 7492(0x1D44) bytes left. The problem should not occur if OEM checks every warning message when they compile the code.

The following instruction results in a device hang:

01A23BE0 E50C7114             str         r7, [r12, #-0x114]  << Crash here since a page in request failed due to stack overflow

               

At this point r12 is 0x24081E70. Thus r7 will be stored in 0x2E081D5C. Note that there are two 4K guard pages for a 64Kb thread stack (in this case the thread stack is 0x24080000 ~ 0x2408FFFF). Note that when you build applications within Platform Builder or the Windows Mobile Adaptation Kit, the default thread stack is 64Kb of reserved virtual memory (the physical RAM is committed one page at a time). This is a pretty reasonable limit for most things on an embedded device. However, when you build your applications in Visual Studio, the default thread stack is 1MB of reserved virtual memory, which is often much more than needed. That is why experienced Windows Mobile application developers will set the default thread stack to 64Kb in Visual Studio (in Project properties à Linker à System à Stack Reserve Size) and then allocate larger stacks only when necessary.

Back to the stack fault above, the two guard pages are: Page A: 0x24082000-0x24083FFFF and Page B: 0x24080000-0x24081FFFF. When Page B is being hit, the kernel will throw an exception for the application to handle. If the application hits Page A, the system will terminate the thread. The above instruction is hitting Page B and the thread will be terminated immediately. For more on thread stack guard pages, see http://blogs.msdn.com/hopperx/archive/2006/02/03/524170.aspx

3.  A Faulty Sample Driver

Now let’s take a look at the sample driver that demos the sample problem. Let’s first see the failure logs and call stacks.

Debug messages:

920555 PID:a377f6ca TID:624727c2 [Stack fault]: Thread=83451bb4 Proc=80314240 'device.exe'

 920557 PID:a377f6ca TID:624727c2 AKY=00000411 PC=019b14dc(baddrv.dll+0x000014dc) RA=019b151c(baddrv.dll+0x0000151c) BVA=161b19a4 FSR=00000005

 

                Call stack:

0x161b19cc BADDRV!StackOverflow(unsigned long 0x00000010)  line 25

0x161b59d8 BADDRV!StackOverflow(unsigned long 0x00000010)  line 34

0x161b99e4 BADDRV!StackOverflow(unsigned long 0x00000011)  line 34

0x161bd9f0 BADDRV!Stack_Fault(unsigned char * 0x00000000, unsigned long 0x00000000, unsigned char * 0x00000000, unsigned long 0x00000000, unsigned long * 0x161bdb6c)  line 20

0x161bda0c BADDRV!Launch_Test_case(unsigned long 0x00000300, unsigned char * 0x00000000, unsigned long 0x00000000, unsigned char * 0x00000000, unsigned long 0x00000000, unsigned long * 0x161bdb6c)  line 40

0x161bda38 BADDRV!BAD_IOControl(unsigned long 0x00000066, unsigned long 0x00000300, unsigned char * 0x00000000, unsigned long 0x00000000, unsigned char * 0x00000000, unsigned long 0x00000000, unsigned long * 0x161bdb6c)  line 78 + 36 bytes

0x161bda68 DEVMGR!DM_DevDeviceIoControl(void * 0x00000000, unsigned long 0x161bdb6c, unsigned long * 0x00000000, _OVERLAPPED * 0x161c5970)  line 464 + 44 bytes

NK!80036520()

 

                Registers:

R0 = 00000010 R1 = 00000000

 R2 = 00000000 R3 = 00000001

 R4 = 019B14A0 R5 = 00000003

 R6 = 00000300 R7 = 00000000

 R8 = 00000000 R9 = 00000000

 R10 = 00000000 R11 = 161BDAA8

 R12 = 161B59D8 Sp = 161B19CC

 Lr = 019B151C Pc = 019B14DC

 Cpsr = 2000001F

 

 Negative=0 Zero=0 Carry=1 Overflow=0

 Q=0

 

 IRQ=0 FIQ=0 Thumb=0

 

 M4=1 M3=1 M2=1 M1=1 M0=1

 

Disassembly:

StackOverflow:

019B14CC    mov         r12, sp

019B14D0    stmdb       sp!, {r0}

019B14D4    stmdb       sp!, {r12, lr}

019B14D8    sub         sp, sp, #1, 18

$M26864:

019B14DC    add         r3, sp, #1, 18

019B14E0    ldr         r3, [r3, #8]

019B14E4    cmp         r3, #0

019B14E8    bhi         |$M26864+14h (019b14f0)|

019B14EC    b           |$M26864+40h (019b151c)|

019B14F0    add         r3, sp, #1, 18

019B14F4    ldr         r3, [r3, #8]

019B14F8    sub         r3, r3, #1

019B14FC    add         r12, sp, #1, 18

019B1500    str         r3, [r12, #8]

019B1504    mov         r3, #1

019B1508    add         r12, sp, #3, 20

019B150C    str         r3, [r12, #0xFFC]

019B1510    add         r0, sp, #1, 18

019B1514    ldr         r0, [r0, #8]

019B1518    bl          |StackOverflow (019b14cc)|

019B151C    add         sp, sp, #1, 18

019B1520    ldmia       sp, {sp, lr}

019B1524    bx          lr

 

The faulting instruction is PC=019B14DC. At that point SP is 161B19CC. We know that for each thread’s stack ranges from xxxx0000 ~ xxxxffff, and 161B19CC falls into the topmost guard page (Please refer to the stack figure in the above example). Therefore when the kernel sees this as one of the operands in this instruction, it will generate the stack fault.

The code that creates big arrays on the thread stack is shown below:

void Stack_Fault( PBYTE pBufIn,

                 DWORD dwLenIn,

                 PBYTE pBufOut,

                 DWORD dwLenOut,

                 PDWORD pdwActualOut )

{

    DWORD dwStackDepth = 18;

    StackOverflow(dwStackDepth);

}

 

 

void StackOverflow(DWORD dwDepthCount)

{

    if(0 >= dwDepthCount )

        return;

 

    dwDepthCount --;

 

    // Create an array on the stack

    DWORD buf[4096];

    buf[4095] = 1;

    StackOverflow(dwDepthCount);

}

Stack_Fafault() calls StackOverflow() recursively. Each time 4Kb of space is allocated on the thread stack. This explains why the thread stack is all used up after three calls of StackOverflow(), as shown in the call stack dump above.

4.  Conclusion

This article discusses stack fault, a common problem with a device driver on Windows Mobile platform. The problem occurs when the guard pages of the 64Kb thread stack is being hit. When you see this problem while running Hopper or other tests, make sure you have the call stack and registers, as well as the assembly code such that you can verify the cause.

Posted by zhengpei | 1 Comments
Filed under:

Debugging Attached Process on Devices

Very often I need to build a quick test EXE or DLL and test it using device emulator. I can of course do this by using Platform Builder's "load from release directory" feature with a KITL enabled image. But this will require a full booting up of the image.

I can also use the "Attach to Process" feature of Visual Studio Smart Device component. First run the test application on a device emulator, then attach the VS debugger to the process. Then when you break the process, you probably see some disassembly code with unresolved addresses. So the question is, how to make better use of this feature for source code debugging?

First, you need to check if the symbol of the test application is loaded. Open the 'Modules' windows and see if the symbol file (PDB) of the test application is showing up there. You should see 'symbol loaded' if you have the PDB file and the EXE/DLL in the same directory where you run the test application.

Then, think about what code is running when you break the process. If you see symbol of the test application is loaded but you did not see any symbol in the disassembly window when you break the process, chances are the process is running code that you don't have the symbols. For example, for a simple Win32 window application created using the wizard, if you break it, you will end up in the message loop somewhere in coredll.dll. If you don't have symbol for it, you will not see any meaningful information in the disassembly window and the call stack window.

A good way to break the test application is to create a breakpoint that you know it will be hit. After attaching the debugger to the process, add a new breakpoint such as "func" (whereas func is a function in the test application).

NOTE: DO NOT USE THE PB METHOD OF ADDING A BREAKPOINT HERE! That is, just enter the function name, not the PB way of "{,,yourapp.exe} func".

Then you should see the breakpoint is resolved and a solid red circle shows up next to it in the breakpoint window. Then when you do something with the application to trigger this breakpoint, you will see the application breaks and its source code shows up! Well, that is based on the assumption that the source code path indicated in the PDB file exists on this computer. If the debugger has trouble finding the source files using that path, it will pop up a nice dialog box for you to specify a path. In that case, just browse to the place where you have the source files.

Now, you can do source code debugging of the process you just attached.

 

Posted by zhengpei | 1 Comments
Filed under:

Cloud Computing: "Save To My SkyDrive"

Disclaimer: this post does not imply anything related to Microsoft Cloud Computing strategy.

What does Cloud Computing (CC) mean to me?  Two services for now:

Microsoft SkyDrive is a service to store and share files on the web, and Google Docs enables online editing and sharing of documents and calendars. (Google Gear allows offline editing).

One feature missing from both services is what I call the "Save To My SkyDrive" on the "File" menu, with which you can edit your stuff in your client application and save it directly to your SkyDrive. Even better, you should be able to create a network drive that maps your SkyDrive to a drive letter, and drag and drop your stuff directly into the drive. 

Looking ahead, I expect a lot (probably not all) of your communication materials on your hard drive will be actually just local copies of the same stuff in the cloud. We already have emails stored somewhere on the Internet so we can access anywhere, anytime, from any computer. We will see a lot more going this direction: your Office docs, your calendar, your personal documents, your health care record, your family photos, etc. In other words, the web, or the cloud, is your big "My Documents" folder, and you are either working offline with some client applications such as Microsoft Office and sync with the cloud later, or working online using web browser based applications to edit your files directly.

The files are not even stored and managed in one single place - for example, your family video may not be saved as a single file on Cloud Server # 314 at Mountain View, CA. Instead, pieces of this file may be stored in various places in New York City, Phoenix, Chicago, and Seattle, and some networking coding scheme is employed to achieve excellent performance and reliability (P2P users should know what I mean here).

And your mobile devices should be doing the same thing - offline editing and online syncing to your corner in the cloud.

One word: web-sourcing. We will see our local storage sourced to the cloud, and a lot of our communications (file editing and review, meeting request, trip planning and expense tracking, etc) can be sourced to the cloud as well.

Why are we heading this way? Two reasons:

  1. Files in your local storage can not be shared with others easily; How often do you have to send attachments of file copies back and forth to your colleagues and family, and to yourself?
  2. How much space do you really need to store your docs/videos/mp3/books? I always need more space ...

Is this trend killing box software manufacturers like Microsoft? Not at all. Client applications are still much more powerful and user-friendly than those browser-based solutions. People still need them. The client software just need to be more CC-ready, creating an enriched user experience that is closely, naturally integrated into the web.

This requires a company-wide initiative to be successful, something like Cloud-Ready Computing (CRC (r) all rights reserved) , just like what Microsoft did with security (Trustworthy Computing). Small features such as "Save To My SkyDrive" should be identified by every participating product group, and the Windows Live services should be extended to provide could hosting, and the Windows Mobile platform should be Cloud-Ready together with other Microsoft products as well instead of always playing the porting/catching-up game.

Update: Microsoft Office Live Workspace (beta) offers similar service as Google Docs.

Posted by zhengpei | 1 Comments
Filed under:

How Many Days to Reach 1 Million?

Last year, iPhone took 74 days to reach 1 million.

HTC Touch took about 5 months to get that number.

This year, the 1 million mark was reached just 3 days after iPhone 2.0 was launched. Now the total iPhone volume has reportedly reached 7 million. Their goal of getting 10 million iPhone shipped by the end of 2008 is well within reach.

I don't have an iPhone 3G. Ironically some people from our customer-facing team often bring their own iPhone to our Windows Mobile partners, which I think is politically incorrect. Anyhow, I tried an iPhone 3G a bit and still the user experience is superior and exchange email sync worked fine.

Meanwhile, there is another big monster lurking around the corner - the Google Android phones. Oh, yes you can say as of today there is no such phone so the ratio of Windows Mobile to Android is 18 million to ZERO, so it is infinite. Great.

But, until 6/29/2007, the ratio of Windows Mobile to iPhone was infinite as well...

Posted by zhengpei | 2 Comments
Filed under:

How to Display all IE Mobile Favorites?

Let's say we want to write an application that displays all the favorites of IE Mobile and allows user to click them. Then IE Mobile should go to that URL.

We can certainly write some code to retrieve all the favorites items from \Windows\Favorites by calling FindFirstFile(). Note that some default favorites are saved in a registry key, so we might want to retrieve those as well. Then we can create a UI to show them, and then launch IE Mobile with the selected URL user clicked.

Or, we can utilize the default home page of IE Mobile, \windows\default_0409.htm. This page has some javascript that will call a window.external.favorites object which will retrieve all favorites into a string array. The javascript code looks like this:

    // Loads the current favorites
    function LoadFavorites()
    {  
        // favorites
        var favorites = window.external.favorites;
         
        for(var i = 0; i < favorites.length; ++i)
        {
             strFavHTML +=  "&nbsp;&nbsp;<a class=\"collection\" href='' onclick=\"window.external.favorites(" +
                            i + ").goTo();return false\">" + favorites(i).name +
                            "</a><br>";
        }  
                         
    }   

We can create a new page to do the same. However, when I copied the page onto the device and loaded it into IE Mobile, I did not see any favorites. What is the problem?

Security. The default home page default_0409.htm has a 'system' attribute! Okay, I changed my html file to be 'system' as well using Pocket Controller, then it worked!

Remaining work is quite simple. Write an application to call CreateProcess() and pass my own htm file name as parameter to IExplore.exe:

    SHELLEXECUTEINFO info;
    memset(&info, 0, sizeof(SHELLEXECUTEINFO));

    info.cbSize = sizeof(SHELLEXECUTEINFO);
    info.fMask = SEE_MASK_FLAG_NO_UI;
    info.lpVerb = _T ("open");
    info.lpFile = L"\\Windows\\IExplore.exe";
    info.lpParameters = L"file://\\windows\\fav.htm";
    info.nShow = SW_SHOW;
    ShellExecuteEx(&info);

My simple page fav.htm looks like this:

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
  <meta name="MobileOptimized" content="240">
  <title>IE Mobile Favorites</title>

    <script>
    var strFavHTML   = "";
    var strHistHTML  = ""; 
    
    // Loads the current favorites
    function LoadFavorites()
    {  
        // favorites
        var favorites = window.external.favorites;
         
        for(var i = 0; i < favorites.length; ++i)
        {
             strFavHTML +=  "&nbsp;&nbsp;<a class=\"collection\" href='' onclick=\"window.external.favorites(" +
                            i + ").goTo();return false\">" + favorites(i).name +
                            "</a><br>";
        }  
                         
    }   
   
 
  </script>
</head>

<body align=center>
<p>My Favorites</p>

<script>
 LoadFavorites()
 document.write(strFavHTML);

</script>
 </body>
</html>

Posted by zhengpei | 1 Comments
Filed under:

Device Hangs: Anti-Virus Software and ActiveSync Deadlock

I've been working on an interesting problem reported by a Windows Mobile partner. They have a anti-virus software installed on the WM6 device. And whenever they copy an infected file from desktop to the device, that anti-virus software will detect that infected file and delete it. After the user sees 'cannot copy file blah blah' in ActiveSync on the desktop side, the device hangs.

So the question is: what causes the device to hang?

Apparently the AV software has something to do with it. It is constantly monitoring any file system changes on the device, trying to scan every new file copied from the desktop side. 

Okay, I've got a full kdmp file, with a corresponding flat release directory with all the symbols (including the AV software symbol files). Attach it to PB, run CEDebugX, I see this (Note I slightly modified the stuff to hide some sensitive information):

 Thread A:

 Thread: 0x89395640 (rapiclnt) hThread=0x6939595a

===========================================================================

NK!SC_TakeCritSec() line 5233

NK!EnterCriticalSection() line 104

NK!SC_LoadLibraryExW() line 4699

COREDLL!int_LoadLibraryExW() line 598 + 60 bytes

COREDLL!stub_LoadLibraryExW() line 352

COREDLL!xxx_LoadLibraryW() line 649

FAVFFILT!DLL_F_CEL_LogMsg(const wchar_t * 0x03ec4134, unsigned long 0x00000002) + 40 bytes

FAVFFILT!FILTER_MoveFileW() + 260 bytes

CACHEFILT!FilterHook_t::MoveFileW() line 379 + 16 bytes

CACHEFILT!CachedVolume_t::MoveHelper() line 903

CACHEFILT!FCFILT_MoveFileW() line 281 + 8 bytes

FSREPLXFILT!FILTER_MoveFileW() line 410 + 28 bytes

FSDMGR!FSDMGR_MoveFileW() line 634 + 32 bytes

COREDLL!xxx_AFS_MoveFileW() line 118

FILESYS!FS_MoveFileW() line 2449 + 16 bytes

COREDLL!xxx_MoveFileW() line 62

RAPICLNT!xxxMoveFile() line 117

 

Thread B:

 

Thread: 0x89397000 (av.exe) hThread=  0xea63f872

===========================================================================

NK!SC_TakeCritSec() line 5233

NK!UB_TakeCritSec() line 5274

COREDLL!xxx_TakeCritSec() line 1857

COREDLL!EnterCriticalSection() line 104

CACHEFILT!CachedVolume_t::CreateFileW(unsigned long 0x00000001, _SECURITY_ATTRIBUTES * 0x00000000, unsigned long 0x00000003, unsigned long 0x00000000, void * 0x00000000) line 665

CACHEFILT!FCFILT_CreateFileW(unsigned long 0x00000001, _SECURITY_ATTRIBUTES * 0x00000000, unsigned long 0x00000003, unsigned long 0x00000000, void * 0x00000000) line 267

FSREPLXFILT!FILTER_CreateFileW(unsigned long 0x00000001, _SECURITY_ATTRIBUTES * 0x00000000, unsigned long 0x00000003, unsigned long 0x00000000, void * 0x00000000) line 76 + 64 bytes

FSDMGR!FSDMGR_CreateFileW(unsigned long 0x00000000, _SECURITY_ATTRIBUTES * 0x00000003, unsigned long 0x00000000, unsigned long 0x00000000, void * 0x0b392002) line 1013 + 76 bytes

COREDLL!xxx_AFS_CreateFileW(unsigned long 0x00000001, _SECURITY_ATTRIBUTES * 0x00000000, unsigned long 0x00000003, unsigned long 0x00000000, void * 0x00000000) line 95

FILESYS!FS_CreateFileW(unsigned long 0x00000000, unsigned long 0x80000000, void * 0x00000000) line 2226 + 48 bytes

NK!SC_CreateFileW(unsigned long 0x00000003, unsigned long 0x00000000, void * 0x00000000) line 2589 + 56 bytes

NK!OpenFileFromFilesys() line 571 + 48 bytes

NK!TryDir(int 0x0000000e, int 0x00000000) line 690 + 28 bytes

NK!TrySameDir() line 728

NK!OpenExecutable() line 806 + 12 bytes

NK!OpenADll() line 3441 + 20 bytes

NK!PerformCallBack4Int() line 2386 + 68 bytes

NK!InitModule(unsigned short 0x0000) line 4105 + 44 bytes

NK!LoadOneLibraryW() line 4442 + 24 bytes

NK!SC_LoadLibraryExW() line 4699 + 20 bytes

COREDLL!int_LoadLibraryExW() line 598 + 60 bytes

COREDLL!stub_LoadLibraryExW() line 352

COREDLL!xxx_LoadLibraryW() line 649

SHUTIL!CePerfOpenSession() line 489 + 24 bytes


[Diagnose] Invoking deadlock diagnose tool

Creating thread list ...

Creating the proxy list...

920 thread proxies.

DEADLOCK DETECTED!

===========================================================================

|

|  Deadlock between rapiclnt av.exe

|

===========================================================================

 --> Critical Section (lpcs = 0x042902cc)

      owned by ...

  rapiclnt thread 0x89395640

      blocked on ...

  Critical Section (lpcs = 0x842f0ba0) LLcs

      owned by ...

  av.exe thread 0x89397000

       blocked on ...

 --> Critical Section (lpcs = 0x042902cc)

rapiclnt.exe is the RAPI client that handles file operations of ActiveSync. av.exe is the AV software. As you can see from the CedebugX output, the two threads deadlocked because Thread B is holding the LLcs, the OS loader lock while trying to get into a critical section. Thread A is doing MoveFile and somehow it is trying to get the loader lock after getting into that critical section that Thread B is waiting to get in. So deadlock occurred. I looked into the code path of Thread A, and figured out the critical section it holds is the file system volume access critical section. When Thread B calls CACHEFILT!CachedVolume_t::CreateFileW(), it tries to enter that file system volume critical section,  which is taken by Thread A.

Then the question is, why Thread A, which is supposedly performing a MoveFile operation, tries to get the OS loader lock? Take a look at Thread A's stack, you will see a file system filter FAVFFILT.dll that performs a LoadLibrary call. Yes, that is why the loader lock is needed. I was told that the file system filter is a third-party software installed on the device. Without knowing the source of the filter, I cannot dig deeper into this issue any more.

Anyway, things have been clear now. The file system filter driver should be fixed: do not call LoadLibrary() because that will require a OS loader lock while the underlying thread is probably holding a file system volume lock. This may lead to a deadlock with other threads calling LoadLibrary().

Posted by zhengpei | 1 Comments
Filed under:
More Posts Next page »
 
Page view tracker