2012年4月15日 星期日

Unknown IOCTL, IOCTL_PSL_NOTIFY

在使用 XXX_IOControl  的時候 發現會有不名的 IOCTL 自動進來
其code 為 0x10303FF (16974847)
經查結果如下
IOCTL_PSL_NOTIFY 是屬於 OAL IOCTL 之一
它在什麼時候被呼叫呢?
也就是當AP Process Main Thread 結束的時候
它呼叫Driver 的 thread 尚未結束(或被block住)
這時系統就會call IOCTL_PSL_NOTIFY 去通知Device Driver unblock, release 這個thread.


The OS uses this I/O control when all of the following conditions are true:
  • The main application thread exits.
  • The application has other threads still running.
  • The application has open file handles that refer to the device.




http://www.itlisting.org/4-windows-ce-embedded/81ac8dc06a35379f.aspx
hey... 
Why does my XXX_IOControl receive a unknown IOCTL code when closing my
application ?? 
The IOCTL code is received before the XXX_Close is called. 
The received code is: 16974847 (0x10303FF) 
What is causing this ???
What is this used for ??? 


This is IOCTL_PSL_NOTIFY (see common\oak\inc\pkfuncs.h).  It's issued when a 
process is exiting. 
Basically what happens is this: when a process exits (i.e. the main thread
is terminating), all threads in that process will be terminated.  Some of
these threads may be blocked inside drivers.  This IOCTL is issued to all
drivers so that they can unblock these threads if they so desire (most
drivers ignore this, but check out the serial driver
(common\oak\drivers\serial\com_mdd2\mdd.c) for an example of how this might
be done. 

2012年4月12日 星期四

ActivateDevice

在WINCE 7 下,用RegisterDevice 會失敗 回傳1060 (ERROR_SERVICE_DOES_NOT_EXIST) 不知道為什麼。

只好改用 ActivateDevice
ActivateDevice 的第一個參數是 Registry Path 不包含HKEY_LOCAL_MACHINE
如 HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Netbios 就變成 "Drivers\BuiltIn\Netbios"

過程如下
當Registry 都沒設時 回傳 1060
當有設好一些 Registry 時 會回傳 1610  (ERROR_BAD_CONFIGURATION)
當都設好時 但是 .DLL 沒放到 \Windows 下 會回傳 2 (ERROR_FILE_NOT_FOUND)
當全部都好後 一直回傳 1 (ERROR_INVALID_FUNCTION)
最後才知道是 XXX_Init 沒有定義 export ( 用到舊的定義 一個參數)


VirtualCopy MmMapIoSpace in WINCE 6

http://discovertheexperience.blogspot.com/2009/04/windows-embedded-ce-60-memory-mapping.html

In Windows Embedded CE 6.0 there are some APIs which can only be called from Kernel Mode due to trust issues. The memory mapping APIs like VirtualCopyMmMapIoSpace (which is a wrapper for VirtualAlloc and VirtualCopy), … now belong to those Kernel Mode only APIs. Consequently you might ask: “So there is no way to call MmMapIoSpace directly from User Mode?” Well not quite, there is but one exception and that is a User Mode driver. The reflector service of a particular User Mode driver which runs in Kernel Mode can call MmMapIoSpace on behalf of that User Mode driver. However, it will not do so unless it knows that the User Mode driver is allowed to access the addresses in question. But how does the reflector service get this information you might ask? Well It gets it from the User Mode driver’s registry: more specific from the IoBase and IoLen keys. You can also use multi-strings here to specify multiple base addresses and lengths. And since this part of the registry is only accessible by privileged applications we have a protection against unauthorized altering of those keys.

But what if you need to call a memory mapping API such asMmMapIoSpace from a User Mode application? How now brown cow? Well you got several options how to deal with this problem:
  • You can make the code that calls the memory mapping functions a driver. Remember to specify the IoBase and IoLenregistry keys if you make it a User Mode driver.

  • You can make the code that calls the memory mapping functions into a DLL that you then have to load into the Kernel via LoadKernelLibrary.

  • You can create a dummy Kernel Mode driver that implementsIOCTL_DO_VIRTUAL_COPY to call VirtualCopy.

There is another important restriction on VirtualCopy and therefore also on MmMapIoSpace in Windows Embedded CE 6.0: Calls to either of these two memory mapping functions will fail if it crosses a 32 MB section boundary. To avoid this you may have to call these APIs multiple times.




http://blog.csdn.net/Jack__h/article/details/4939911
http://www.cppblog.com/milkyway/archive/2007/03/27/20738.html


VirtualCopy 的WINCE 5, 6, 7 的解釋各有不同,值得一看
WINCE 5 -- 傳統的, MEM_PHYSICAL 解釋不同, return 的address 2MB 不同
http://msdn.microsoft.com/en-us/library/aa450977.aspx
WINCE 6  -- 講了如何call API 的替代方法
http://msdn.microsoft.com/en-us/library/ee483154(v=winembedded.60).aspx
WINCE 7
http://msdn.microsoft.com/en-us/library/ee483154.aspx

2012年3月4日 星期日

SuperFloopy, USB Stick without partition problem

在舊版的WinCE 系統遇到了一個奇怪的問題
有一些新的USB Flash, 使用WINCE 來Format
之後 在舊版的WINCE 5.0 上不能讀取
但在較新的WINCE 5.0 (可能更新過) 讀取沒有問題

2. 後來發現這些會有問題的 flash disk, 竟然沒有 partition table, 又稱為 superfloopy.
3. 如果把這些flash 用Windows 7 format, 結果在 Windows 及 WINCE (old)都能讀

4. 經過非常仔細地比較 Windows 及 WINCE format 出來的內容, Boot, FAT, ...
找不出可疑的地方。 最後,竟然在不可能的地方發現。
原來Boot Sector 下方的字串區,WINCE 竟然會去比較。
而且比較的方式相當奇怪 並且找不出規則。

5. 後來 I realize , WINCE 是試著去讀取 partition table,WINCE 正常所 format 的值, 都為0 ,所以檢查不過,就不會load。而 Windows 7 所format 的值 剛好為字串區,剛好又符合WinCE 的檢查, 所以 ok.

6. solution. make false partition table data for WINCE to check.
一,要有兩個partition
二,  partition 1 的 LBA start address 要比 partition 0 的start address 小才行。兩個partition 的size 不能為0即可。
三, 兩個partition 的 type 要設  (如0x05) 不然Windows 7 會認不出並提示你format disk。

7. 問題總結。
一,起源是因為新的一些flash (SuperFloopy) 並沒有partition table, 第一個Physical Sector 就是Boot Sector MBR。
二,舊的WINCE 並不知道,一樣檢查partition table 然後拒絕載入。WINCE所format 的boot sector 這附近皆為0.
三, Windows 7 所format 的 boot sector,partition table 附近為顯示字串, 而且值剛好可以過關, 所以Windows 所format 的superfloopy 在舊的WINCE 沒問題。
四,較新的WINCE 5.0 應該有改過檢查的 code, 所以不管從裡format 的flash   都能用。
五, 其實Windows 7 一樣沒有handle this correctly, 一樣會去讀取partition table 並檢查, 在某些資料下(如有Start Sector, partition size, 但沒有partition type ), 會認為這個Disk 是unformatted 並提示使用者format.


related information but not this problem
http://support.microsoft.com/kb/904255

[HKEY_LOCAL_MACHINE\System\StorageManager\FATFS]
"BypassFATSectorCheck"=dword:1

2012年2月29日 星期三

Access Physical Disk Content ( partitiion, boot sector, FAT)

Physical Disks and Volumes

Direct access to the disk or to a volume is restricted. For more information, see "Changes to the file system and to the storage stack to restrict direct disk access and direct volume access in Windows Vista and in Windows Server 2008" in the Help and Support Knowledge Base athttp://support.microsoft.com/kb/942448.
Windows Server 2003 and Windows XP:  Direct access to the disk or to a volume is not restricted in this manner.
You can use the CreateFile function to open a physical disk drive or a volume, which returns a direct access storage device (DASD) handle that can be used with the DeviceIoControl function. This enables you to access the disk or volume directly, for example such disk metadata as the partition table. However, this type of access also exposes the disk drive or volume to potential data loss, because an incorrect write to a disk using this mechanism could make its contents inaccessible to the operating system. To ensure data integrity, be sure to become familiar withDeviceIoControl and how other APIs behave differently with a direct access handle as opposed to a file system handle.
The following requirements must be met for such a call to succeed:
  • The caller must have administrative privileges. For more information, see Running with Special Privileges.
  • The dwCreationDisposition parameter must have the OPEN_EXISTINGflag.
  • When opening a volume or floppy disk, the dwShareMode parameter must have the FILE_SHARE_WRITEflag.
Note  The dwDesiredAccess parameter can be zero, allowing the application to query device attributes without accessing a device. This is useful for an application to determine the size of a floppy disk drive and the formats it supports without requiring a floppy disk in a drive, for instance. It can also be used for reading statistics without requiring higher-level data read/write permission.
When opening a physical drive x:, the lpFileName string should be the following form: "\\.\PhysicalDriveX". Hard disk numbers start at zero. The following table shows some examples of physical drive strings.
StringMeaning
"\\.\PhysicalDrive0"Opens the first physical drive.
"\\.\PhysicalDrive2"Opens the third physical drive.

To obtain the physical drive identifier for a volume, open a handle to the volume and call the DeviceIoControl function withIOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS. This control code returns the disk number and offset for each of the volume's one or more extents; a volume can span multiple physical disks.
For an example of opening a physical drive, see Calling DeviceIoControl.
When opening a volume or removable media drive (for example, a floppy disk drive or flash memory thumb drive), the lpFileName string should be the following form: "\\.\X:". Do not use a trailing backslash (\), which indicates the root directory of a drive. The following table shows some examples of drive strings.
StringMeaning
"\\.\A:"Opens floppy disk drive A.
"\\.\C:"Opens the C: volume.
"\\.\C:\"Opens the file system of the C: volume.

You can also open a volume by referring to its volume name. For more information, see Naming a Volume.
A volume contains one or more mounted file systems. Volume handles can be opened as noncached at the discretion of the particular file system, even when the noncached option is not specified in CreateFile. You should assume that all Microsoft file systems open volume handles as noncached. The restrictions on noncached I/O for files also apply to volumes.
A file system may or may not require buffer alignment even though the data is noncached. However, if the noncached option is specified when opening a volume, buffer alignment is enforced regardless of the file system on the volume. It is recommended on all file systems that you open volume handles as noncached, and follow the noncached I/O restrictions.
Note  To read or write to the last few sectors of the volume, you must call DeviceIoControl and specifyFSCTL_ALLOW_EXTENDED_DASD_IO. This signals the file system driver not to perform any I/O boundary checks on partition read or write calls. Instead, boundary checks are performed by the device driver.

上面寫的是在Windows 環境
而在WINCE 中,要 Open 的 filename 應該是像 L"\\USB Disk\\Vol:" <-- 錯 要用 L"DSK1:" 注意有冒號
CreateFile 成功後,再用DeviceIoControl  IOCTL_DISK_READ
用 L"\\USB Disk\\Vol:" 會成功但是之後 DeviceIoControl  IOCTL_DISK_READ 會 hang

IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
http://a-jordan.blogspot.com/2008/05/usb-flash-physical-drive.html

2012年2月2日 星期四

USB flash problem, 沒有partition, superfloopy

最近有一個問題
就是用WINCE 5.0 format 的 USB Flash
沒辦法在USB200下讀取

仔細檢驗了一下不能讀取的USB Disk
發現竟然沒有partition table

查了一下 沒有 Partition 的 Disk
就叫 Super Floopy

http://msdn.microsoft.com/en-us/windows/hardware/gg463525


Q.What about removable media?
  
A.Removable media must be MBR or "superfloppy."
Q.What is a superfloppy?
  
A.
Removable media without either GPT or MBR formatting is considered a "superfloppy." The entire media is treated as a single partition.
The media manufacturer performs any MBR partitioning of removable media. If the media does have an MBR, only one partition is supported. There is little user-discernible difference between MBR-partitioned media and superfloppies.
Examples of removable media include floppy disk drives, JAZ disk cartridges, magneto-optical media, DVD-ROM, and CD-ROM. Hard disk drives on external buses such as SCSI or IEEE 1394 are not considered removable.

2012年1月17日 星期二

mem_fun_ref, for_each

在試著使用for_each 的時候, 發現了一些問題
也把for_each 的定義看過了一遍, 也更加了解其工作原理

for_each 的第三個參數
要怎麼寫才會漂亮呢

1. static function
2. member function
3. lambda function

看其定義


for (; _ChkFirst != _ChkLast; ++_ChkFirst)
_Func(*_ChkFirst);
return (_Func);

這個function 會以 *_ChkFirst 為參數
所以只能用 static function

void aa ( *_ChkFirst )
{ ... };

for_each(  ,  , aa );

用 member function 的話, 則會失敗, 因為member function 會隱含性地多加 this
參數

用 static member function 的話則ok
for_each(  ,   , &class::static_mem_function );

不想上面這種方法時就要用到 mem_fun_ref 或 mem_fun
此時這個 member function 不用有 ( *_CheckFirst ) 這個參數