2012年4月25日 星期三

Apple Lossless Codec (ALAC)

Apple Lossless 已經open source 了, 是一個很好的選擇
試著build , Windows 的版本 很簡單 沒啥問題 只是如果用VS2010 以前的
要自己下載 stdint.h
stdint.h 是 C99 標準 可以在 http://code.google.com/p/msinttypes/ 下載

然後build MIPS 版本
會出現 error C2733: second C linkage of overloaded function 'wmemchr' not allowed

那是因為 stdint.h include wchar.h
而且加上 extern "C"


#ifdef __cplusplus
extern "C" {
#endif
#  include
#ifdef __cplusplus
}

因為 C 不能 第二次 link 到 overloaded function
所以會出現C2733 錯誤
而且Apple  Lossless Solution 把一些 .c 檔都當成 c++ (/TP) 來 compile

如果把那些  .c 檔用 c 的方式來compile 就不會出現 C2733
不過會出現奇怪錯誤 error C2054: expected '(' to follow 'inline'
那是因為 C 沒有 inline keyword 要用 __inline

2種改法都行

應該是 sdk 中的 wchar.h 有問題 跟 win32 的 wchar.h 不一樣
sdk 中的 wchar.h 好像有明顯錯誤

在win32 中 wchar.h

wmemchr, wcschr, wcspbrk, wcsrchr, wcsstr
都是用 extern "C++" 括起來
但是 standard sdk 中卻沒有(應該是錯誤)
如果修改,移出 extern "C" 然後把 wmemchr, wcschr, wcspbrk, wcsrchr, wcsstr
用 extern "C++" 括起來, 就可以過關

第三種改法
改 stdint.h , extern "C" 改成 extern "C++"

#ifdef __cplusplus
extern "C++" {
#endif
#  include
#ifdef __cplusplus
}




然後繼續編譯, Link 出現一些問題
0. Link subsystem specify WindowsCE
1. unresolved external symbol __security_check_cookie 使用 /GS- 即可 ( Buffer Security Check OFF )
2. memset... function 沒有
要Link coredll.lib 或 corelibc.lib
在此不能用 coredll.lib 因為沒有 startup function like mainACRTStartup 
也沒有 exit()

http://msdn.microsoft.com/en-us/library/ms859584.aspx

最後 編譯完的EXE 到 MIPS上跑
結果不能run 顯示 cannot find one of its component
不知道少了什麼
只好用 dependency walker
http://www.dependencywalker.com/
發現少了 msvcr90d.dll
解決方法之一 是把 compiler option /MDd 改成 /MTd
就ok了 ^^

http://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.80).aspx
http://blog.monkeypotion.net/gameprog/beginner/love-and-hate-between-msvc-and-crt


Exception
事情總是沒那麼簡單,alacConvert 實際上在MIPS run 時,出現了Exception
code 是 0x80000002  address 000124A8
怎麼看 exception code 呢
之前都沒仔細研究
後來查到有關的 2個 API  GetExceptionCode 跟 RaiseException


追到 Exception Code 的定義在 winbase.h 然後又定義在 winnt.h(WIN32) 或 ntstatus.h (ARM)



#define EXCEPTION_ACCESS_VIOLATION          STATUS_ACCESS_VIOLATION
#define EXCEPTION_DATATYPE_MISALIGNMENT     STATUS_DATATYPE_MISALIGNMENT
#define EXCEPTION_BREAKPOINT                STATUS_BREAKPOINT





最常見的是 
EXCEPTION_ACCESS_VIOLATION          0xC0000005
EXCEPTION_DATATYPE_MISALIGNMENT     0x80000002
這兩個


再來 alignment fault 可以用 __unaligned 來解決或者自己copy (byte by byte)

Address 的話, 產生 .map 檔跟 listing files來觀察即可

note: __unaligned 是Microsoft specific
在Linux 中, 用 get_unaligned() 和 put_unaligned() macro


The easiest way to avoid unaligned access is to use the get_unaligned() and
put_unaligned() macros provided by the  header file.


http://lwn.net/Articles/260456/

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.