剛加入部落格園。雖然以前也經常在園子裡晃悠,但只記得欣賞大牛們的大作了,從來沒灌過水。這算是我的處女貼,權當是給園子增加流量了。
畢業走出校門,找了份編程的差事。
剛一上崗,就接到項目組長指派的任務:用Win32 API編程實現Windows XP中FAT32格式的檔案夾唯讀共用,為啥要強調是FAT32格式呢?原來在我來之前,現在這個項目的老版本裡已經實現了NTFS格式的檔案分享權限設定,現在是應客戶的要求添加對FAT32格式的支援。
估計是項目組長認為這個問題實在是太簡單了,已經有了現成的葫蘆,照個畫個瓢就行了,這種低級的任務也只有我這個新來的菜鳥值得花功夫去弄一下。
我剛開始也認為這個任務應該不難,雖然我絕對是個Win32 API編程的菜鳥,以前從來沒用接觸過這東西。一方面是在我以前的編程任務中用不著,另外也是沒膽量碰這東西,光是一堆字串轉換就把我給暈死了。
好了,廢話少說,開始談正事。
首先說下Windows作業系統下NTFS和FAT32檔案格式在檔案分享權限設定,讀寫權限設定方面的區別,簡單點說就是:
- NTFS檔案系統自身可以設定檔案和檔案夾的讀寫存取權限,而FAT32檔案系統則不具備這樣的功能;
- NTFS檔案系統的讀寫存取控制對於本機使用者訪問以及通過檔案夾共用的網路訪問均有效;
- 檔案夾共用也有自己的存取權限設定,但這種存取控制機制僅對網路訪問有效,對本機使用者訪問不起作用;
- 如果共用的檔案夾在NTFS分區,則網路訪問同時受到共用使用權限設定和NTFS檔案系統使用權限設定的控制,最終的約束結果為兩者中較嚴格的那一項約束。
更具體的資訊請參考:http://technet2.microsoft.com/windowsserver/en/library/ee26f971-c9d4-444f-9622-d5d756229e5e1033.mspx?mfr=true
為了更直觀的表達這些意思,可以看下下面的:
首先,取消掉Windows XP預設的“使用簡單檔案夾共用”,再分別查看FAT32分區和NTFS分區中檔案夾的“屬性”對話方塊:
左側的對話方塊為FAT32格式的,右側的為NTFS格式的,可見後者比前者多了一項:安全。
開啟兩個對話方塊中都有的“許可權”,再開啟NTFS屬性對話方塊中的“安全”:
這就是我們通過Windows UI設定存取權限的地方了,左邊的許可權僅對網際網路共用控制器作用,右邊的屬於NTFS特有的存取控制功能,對於本機使用者訪問和網路訪問都有效。
以上示範的是通過windows UI設定許可權的方法,另外,對於我們這些吃編程飯的人來說,還有必要知道有沒有相應的DOS命令來實現同樣的功能。對於左側的設定網路存取權限的功能,我還沒有找出相應的命令(要是很容易找到這樣的命令,我就不在這裡灌這桶水了:));對於右側的設定NTFS存取權限的功能,有一個專用的DOS命令可以使用:cacls,用法請參考DOS協助或參考MS的資料:http://support.microsoft.com/kb/318754/
說了這麼多,貌似還是沒有切入正題,我想說的是該怎麼編程啊,暴汗~~
先說下如何用API編程實現NTFS的檔案夾共用:
- 調用API函數NetShareAdd()將檔案夾設定為共用,調用此函數後如果不做其他設定,網路使用者是無法訪問共用資料夾的,因為此檔案夾在NTFS分區中,同時受到NTFS檔案系統的存取控制,因此還需要第2步;
- 調用DOS命令cacls,賦予Guest使用者組讀寫權限;
- 如果要取消檔案分享權限設定,直接調用API函數NetShareDel(),完事。
這就是項目中老版本所採用的方法,從完成後的代碼上看,還是比較簡單明了的,思路上沒有拐多大彎(典型的事後諸葛亮,別人不知道花了多少精力,走了多少彎路才找到這個解決方案,然後把寫好的代碼拿給你看,你看到程式碼數並不算多,就說:這麼簡單啊~~)。
對於FAT32分區中檔案夾,cacls命令是不起作用的,這個命令專用於NTFS格式下的檔案和檔案夾。也就是說上面這種解決方案的第2步不能用了,那麼現在只能使用NetShareAdd()函數添加檔案分享權限設定。調用此函數後如果不做其他設定,網路使用者可以訪問共用資料夾,但擁有完全控制許可權(這是預設的共用使用權限設定),而在實際項目中我們希望能夠編程式控制制讀寫權限。在NTFS分區中,我們還有NTFS檔案系統的存取控制功能罩著,在FAT32分區中就只能依賴於作業系統檔案夾共用自身的使用權限設定功能了。
現在開始切入核心問題了,如何編程設定檔案夾共用的讀寫權限?
DOS命令我是不指望了,至少到目前我還沒找到能實現這一點的命令;只能靠API,不過一開始,NetShareAdd()這個API就迷惑了我很長時間,暈死~~
NetShareAdd函數有一個參數:LPBYTE buf,是指向一個結構體的指標,如果將level參數設為2,則buf所指結構體的定義如下:
1typedef struct _SHARE_INFO_2
2{
3 LPWSTR shi2_netname;
4 DWORD shi2_type;
5 LPWSTR shi2_remark;
6 DWORD shi2_permissions;
7 DWORD shi2_max_uses;
8 DWORD shi2_current_uses;
9 LPWSTR shi2_path;
10 LPWSTR shi2_passwd;
11} SHARE_INFO_2,
12 *PSHARE_INFO_2,
13 *LPSHARE_INFO_2;
注意其中的一個成員:DWORD shi2_permissions,餓滴神啊,莫非這就是我的救星?也來的太容易了吧!?
但之後反覆而痛苦的實驗告訴我,actually,It doesn't work!!!無論將這個傢伙設成多少,對於函數的執行效果都沒什麼影響。在CSDN,MSDN,cnblog(呃,貌似園子裡沒功夫討論這種雞毛蒜皮的小問題)上搜尋,到處都是關於這個參數的用法的疑問,以及求教如何?FAT32檔案夾唯讀共用的文章,後來在MSDN的一個角落裡看到說對於不支援user level的作業系統,此參數無效……
希望再次落空,此時,我,一個剛接觸Win32 API一個半星期的菜鳥,已經在這個“小問題”上花費了一個星期的時間。此時還真有些誠惶誠恐的感覺,這麼簡單的問題,搞了一個星期的都沒個結果,真應該把你給T了,不過幸好老闆沒有將我的恐懼轉化為他的行動,再次暴汗~~
沒辦法,只能硬著頭皮找其他的路子了。經過反覆的找資料,反覆的實驗,反覆的失敗,然後再反覆的找資料,orz,總算是找到設定共用許可權的解決方案了,具體過程還是留給下個文章吧(我的處女貼就這麼點內容,怎麼寫了這麼長時間?)
ps:這裡怎麼在Normal模式下讓兩張貼圖並排顯示?我搞了老半天才在在HTML下弄好,暈~~