如何判別是否為 DRM 的 ASF 檔案?

如何判別一個 ASF 檔案是否為 DRM 的 ASF 檔案?
詳情資料可以參考微軟提供的 Specification: Advanced Systems Format (ASF) Specification
大致上很簡單,一個 ASF 檔案主要有三個部分: Header Object, Data Object, Index Object.
而每個部分又各由不同的 Object 所組成.
要分辨是否為 DRM,主要是在 Header Object 裡面找尋是否有 Content Encryption Object.
那麼要怎麼找尋呢?? OK, 每個 Object 的最前面有唯一的 GUID,你可以依據 GUID 來找到.
而這些,你都可以在 Specification 的後面幾張找到 ( 或者你可以搜尋 ASF GUIDs ).
至此,寫起來並不太困難.程式碼如下:

typedef unsigned long UINT32;
typedef unsigned short UINT16;
typedef unsigned char UINT8;
typedef int BOOL;
enum BOOLEAN
{
FALSE = 0,
TRUE
};
typedef struct GUID_s
{
UINT32 id1;
UINT16 id2;
UINT16 id3;
UINT16 id4;
UINT8 id5[6];
}GUID;
//Content Encryption Object
GUID ASF_Content_Encryption_Object_guid =
{
0x2211b3fb,
0xbd23,
0x11d2,
0xb7b4,
{
0x00, 0xa0, 0xc9, 0x55, 0xfc, 0x6e
}
};
/*
typedef struct ContentEncryptionObject_s
{
GUID objectID;
UINT32 objectSize; // objectSize should be QWORD, 8 bytes, but CCS has not this type.
UINT32 objectSize1;
UINT32 secretDataLength;
BYTE* secretData; // according secretDataLength
UINT32 protectionTypeLength;
char* protectionType;
UINT32 keyIDLength;
char* keyID;
UINT32 licenseURLLength;
char* licenseURL;
}ContentEncryptionObject_t;
*/
//extern CF_FILE* filePtrR;
typedef FILE CF_FILE;
CF_FILE* filePtrR;
long
FILEr_ftell()
{
return ftell( filePtrR );
}
int
FILEr_fseek( long filepos, int whence)
{
return fseek( filePtrR, filepos, whence );
}
long
FILEr_fread( UINT8* ptr, long length )
{
return fread( ptr, 1, length, filePtrR );
}
char* SDRAM_HOLE = NULL;
BOOL
isASFDRM( )
{
long filePos;
char* spaceForParsing = (char*)( SDRAM_HOLE + 0x800000 ); // use the space after 8 MB, prevent conflict
int GUIDLen = sizeof( GUID );
int iter, len = 0;
BOOL bFound = FALSE, bResult = FALSE;
UINT32 headerObjectSize = 0;
UINT32 secretDataLength=0;
UINT32 protectionTypeLength=0;
char* protectionType=NULL;
long readLen=0;
char* encryptionPos = NULL;
// save file position
filePos = FILEr_ftell();
// seek to the start position
FILEr_fseek( 16, 0); //SEEK_SET
FILEr_fread( (UINT8*)&headerObjectSize, 4 ); // we should read 8 here, but ….
// read all header object
// then search the specified GUID, use pattern compare
FILEr_fseek( 0, 0 ); // SEEK_SET
readLen = FILEr_fread( spaceForParsing, headerObjectSize );
len = headerObjectSize – GUIDLen;
// searching.
for( iter = 0; iter objectID
encryptionPos = spaceForParsing + iter;
// ( encryptionPos + GUIDLen ) ==> objectSize
// ( encryptionPos + GUIDLen + 8 ) ==> secretDataLength
secretDataLength = (UINT32) *( encryptionPos + GUIDLen + 8 );
// ( spaceForParsing + iter + GUIDLen + 8 + 4 ) ==> secretData
// ( spaceForParsing + iter + GUIDLen + 12 + secretDataLength ) ==> protectionTypeLength;
protectionTypeLength = (UINT32) *(encryptionPos + GUIDLen + 12 + secretDataLength );
protectionType = (char*) (encryptionPos + GUIDLen + 12 + secretDataLength + 4 );
if( strncmp( protectionType, “DRM”, 3 ) == 0 )
bResult = TRUE;
OnFinally:
// restore file position
FILEr_fseek( filePos, 0); //SEEK_SET
// return result.
return bResult;
}
int main(int argc, char* argv[])
{
SDRAM_HOLE = (char*) malloc( 0x800000 * 2 );
filePtrR = fopen( “00 Cannot Play.wma”, “rb” );
if( isASFDRM() )
printf(“is a drm file.\n”);
else
printf(“not a drm file.\n”);
fclose( filePtrR );
return 0;
}

ok, 程式裡面你會發現一些奇怪的地方,是的,因為我需要在 embedded 環境下運作,所以為了符合環境,所以做了一些調整,不過你還是可以在 Visual C++ 上來運行這段代碼.
看不順眼的,就自己調整吧…
這份 specification 其實斷斷續續看一陣子了,都沒怎麼專心看,不過昨天看的時候,突然開竅了,於是就把這麼一段代碼搞定了.
真神奇啊….

來到崑山

昨天晚上來到公司在崑山的廠區,即將在這裡呆三個星期….(希望是只有三個星期…)
剛來的第一個印象,就是…..我又收假了嗎??
感覺上跟以前在鳳山步校當兵的時候一樣,廠區大大的,也是切割成一塊一塊的~~
真的是太像了.
大致上該帶的東西都帶了,唯一的誤算是天氣,有些涼,沒想像中那麼的熱.
看來得每天洗冷水澡,增強抵抗力了.

不知所云

數週前….
小E:”啊~~整個改成這樣子以後,這邊可能會有問題….”
小E:”嗯…..怎麼辦…先記起來好了….到時候再說…”
今天…
H哥:”喔~~這邊沒辦法試播放影片!!小E,該怎麼辦??”
小E:”我知道這邊,我想一下…”
H哥:”這邊當初沒想到,這不能怪你…”
小E:”我想可以這樣子作…”
H哥:”我想也是這樣子…”
不知道為什麼….
小E:”我早就知道了…”
H哥:(驚愕貌…)”你早就知道了?!”
小E:”我的意思是…”
(一陣混亂….)
事後…
小E, 你在講什麼啊?!
就裝傻說不知道就好啦…

跳槽到 CentOS 3.4

昨天把家裡的 server 從原來的WBEL 改為 CentOS 了.
跳槽的原因….嗯….沒什麼特別的,只因為 CentOS 的 mailing list 比較活躍,更新速度感覺上也比較快.
步驟也是簡單到不行….CentOS 官方網站上有提供FAQ.
照步驟作,網路夠快,裝的套件也不多的話,很快就裝完了…
下次的目標是從 3.4 升級到 4, 不過看起來有蠻多困難的. 畢竟 kernel 換到 2.6 ,處理 hardware 的方式也變了挺多的, 找了一下,大部分都建議燒成光碟片,以光碟開機來作昇級.
再找時間試試看吧.

Upgrade to MediaWiki 1.4.4

鬼混了很久,終於把家裡的 wiki 升級到 1.4.4 了.
升級方法還挺簡單的.
1. 備份你的 LocalSettings.php / AdminSettings.php
2. 把下載來的 MediaWiki 1.4.4 tarball 解壓以後整個蓋過去.
3. 切到 maintenance 目錄下, 執行 php update.php
4. 收工.
真的很簡單吧….
下個目標是把 VFP Wiki 升級到 1.4.4 …

從拍戲看 XP

出自:藍藍的 movie blog – 拍戲沒劇本
轉貼一部分…

首先,他說:「我是編劇出身的,當然知道劇本的重要,但是我更清楚,真正的電影不是在紙上完成的,所有的劇本只是個藍圖,在拍攝的過程裡一定會有改動。」
其次,王家衛強調:「電影上有些東西是無法用文字說明白的,例如一種表情,怎麼用文字說它呢?有時候就是一個特寫,比千言萬語更重要,男女主角為什麼會相愛,只要鏡頭讓你感到他們會相愛,那就對了。電影就是要讓你看見,讓你相信。」
第三點呢,王家衛的說法是:「在拍攝《手》的過程裡,我先拿「薄暮的舞女」原著小說給鞏俐看,告訴她簡單的故事大概,告訴她我打算怎麼拍,然後我就儲一路寫劇本,開工前就交給演員,有時候會再改,會再修。對演員來說最困難的是她可能無法知道每一場戲之間的相互關係,她不能控制故事的流程,只能一場接一場地演。」

看完這篇文章,發現這些導演幹的就是 XP (Extreme Programming) 呀~~
先捉出一個大方向,每天早上決定接下來要作的東西,晚上驗收.
很像,不是嗎??

林志玲與大蕃薯

聽力嚴重退化中…
看林志玲的優格廣告很久了,一直搞不清楚她大叫的是什麼話.
我以為是”大蕃薯”,可是大蕃薯跟優格有什麼關係呢??
這個疑問一直存在我心中好久好久………好想問她本人,到底在講什麼喔…
直到前幾天,和太太看電視的時候,又再次看到這廣告,
我就問我太太說:”她大喊的是什麼啊??為什麼是大蕃薯啊??跟優格有什麼關係啊??”
太太說:”是打分數,不是大蕃薯…”
我(恍然大悟貌):”原來如此啊….我懂了…..”

WinCVS branch and merge

CVS 該怎麼 branch 與 merge ??
其實 CVS 手冊上都蠻清楚的…
只是看起來很模糊,再加上我用的是 WinCVS … 網路上對 WinCVS 的著墨實在是不多….
如何 branch ??
進入 WinCVS 以後, 選 [Remote][Create a branch]
把 Branch name 與 Module name 填一填就好了.
Branch name 你可以自訂,但第一個字母不能是數字.
Module name 就是你的專案名稱…
接下來,該怎麼在 branch 上開發呢??
首先你要先把原先的內容備份,然後重新以新的 branch name checkout, 也就是選[Remote][Checkout module] 的時候,得特別選到 “Update Options”, 勾選 “By revision/tag/branch”, 並填入你剛剛建立的 branch 名稱, 這樣就行了.
接下來,就照一般的開發步驟就行了,每次 commit 以後,你會發現 Rev 欄的號碼跟 Main trunk 的 rev 不太一樣,這表示是正確的.
最後要怎麼 merge 呢??
一般來說,不會有 branch 去 merge main trunk 的狀況….我當初就想幹這蠢事,結果發現根本沒辦法做…. >_<
都是從某一 branch 去 merge 某 branch, 或是從 Main trunk 去 merge branch.
首先,得先 checkout Main trunk 下來,接著選 Update, Update 的時候要特別去選 "Merge Options", 把 Merge type 選為 "Merge with one rev/tag", 填入你要 merge 的 brankch name 即可,其他地方不需要特別勾選.
這邊有一個地方要特別注意,就是該 branch 一定要有更動過 (也就是有 commit 新東西上去 ), 才可以 merge, 否則會都沒反應…
Merge 完以後,你就可以去處理 conflict 或是測試看看有沒有問題,然後把有更動的檔案都 commit 上去就好, 換言之, merge 以後並不會馬上生效,而是還要再 merge 才生效.

2005/04/28

已經有人做出我想做的東西了(IM-Bot),他的應用是字典, Jan’s Tech Blog 介紹到了…
http://www.azuremedia.net/tech/history/web/001104.html
以下是轉貼自 http://charlesc.ilovemeow.net/archives/000315.html

Feedster的Corporate Blogging Policy值得參考,摘要一下:
1. 告知讀者,個人網誌不代表公司立場。
2. 不可洩漏公司機密。
3. 發表與公司的生意相關的想法時要謹慎。
4. 尊重公司、員工、顧客、合作伙伴。
5. 連結或使用公司商標時需經過同意。
6. 公司有可能因安全性或法律問題,要求員工暫時停止blogging。

cache set
介紹:http://blog.xuite.net/frogbsd/geek/113608
下載點:http://www.sysinternals.com/ntw2k/source/cacheset.shtml

微涼的風/孩子

陳綺貞出精選輯了,這次拍的MV,裡面有一首是”孩子”,讓我想起他的第一張專輯.
那時候,我以為他可能只出一片,之後就轉作詞作曲了,所以贊助我弟去買了這張專輯.
後來,完全脫離我的猜測,又出了好幾片 😉
這張專輯非常地迷人….整張都很好聽~幾乎每天都在聽他的歌.
仔細想想也是四五年前的事情了,那是談戀愛的年代.是故,專輯的第二首歌特別吸引我,有戀愛的心情.所以呢,我把歌詞都記起來了.嗯嗯~~不知不覺又掉進回憶的漩渦…..
微涼的你
作詞:陳綺貞
作曲:林暐哲
專輯:讓我想一想
迎著微微的風 像微微的你
在我不經意的時候掀起一陣漣漪
躲著涼涼的雨 像涼涼的你
偶爾捎來消息 將我整天灼熱的思緒撫平
在夜裡 在黎明
融化我凝結的心
擁抱一陣微涼的風
心的空隙任你來去
我睜大了眼睛
找尋不到你
飄散的髮留住了你
微笑的臉卻來不及溫習你的吻
回憶才是你唯一的痕跡
歌名:孩子
作詞:陳綺貞
作曲:陳綺貞
專輯:讓我想一想
夜已晚得很美麗
天已亮得很分明
我在你的回憶裡
是黃昏還是黎明
是否愛得不徹底
我也早已分不清
面對鏡子裡面的自己 話不投機
也許 我真的傻得可以
竟然還不懂你的暗示
我還把我自己當作是 你最疼的孩子
我想 我真的傻得可以
其實我已經迷失自己
我還把我自己當作是 你的唯一