アプリケーションから共有フォルダーにアクセスすると、予期しないエラーが返されます
この記事では、アプリケーションから共有フォルダーにアクセスするときに発生する予期しないエラーの解決策について説明します。
適用対象: Windows Server 2012 R2
元の KB 番号: 2990989
現象
次のような状況で問題が発生します。
- Windows Server 2008 R2 で共有フォルダーを作成し、そのフォルダーに対してユーザー A の読み取りアクセス許可を付与します。
- 共有フォルダーにサブフォルダーを作成し、サブフォルダーの親フォルダーからの継承可能なアクセス許可を無効にし、サブフォルダーに対してユーザー A の読み取りアクセス許可を付与しません。
- ユーザー A としてWindows Server 2012 ベースのサーバーにログオンし、共有フォルダーに対して FindFirstFile を呼び出すアプリケーションを実行します。
このシナリオでは、アプリケーションは失敗します。 さらに、エラー ERROR_ACCESS_DENIEDは期待どおりに返されません。 代わりに、次のいずれかのエラー コードが返されます。
予期しないネットワーク エラーが発生しました。 (ERROR_UNEXP_NET_ERR)
パラメーターが間違っています。 (ERROR_INVALID_PARAMETER)
実行中のアプリケーションが、適切なアクセス権がないことを通知するためにこの状況でERROR_ACCESS_DENIEDが返されると想定している場合は、この想定が正しくない可能性があります。
原因
この問題は、STATUS_ERROR_ACCESS_DENIEDで I/O が失敗する状況で、カーネル モード SMB コンポーネントがSTATUS_UNEXPECTED_NETWORK_ERRORを返すからです。 同時に、SMB コンポーネントは別のスレッドの I/O を要求します。 このスレッドは、STATUS_INVALID_PARAMETERを返すことができます。
SMB コンポーネントから返されるこれらの NT 状態は、NT 状態がファイルまたはフォルダー API に渡されると、次のいずれかの Win32 エラーに変換されます。
- ERROR_UNEXP_NET_ERR
- ERROR_INVALID_PARAMETER
解決方法
アプリケーションがこの状況でERROR_ACCESS_DENIEDが返され、アクセス権がない共有フォルダーのサブフォルダーにアクセスするときにERROR_UNEXP_NET_ERRまたはERROR_INVALID_PARAMETERを受け取るかどうかを判断する場合は、ERROR_ACCESS_DENIEDを受信したときと同じ処理を実行することで、この問題を回避できます。
詳細
サブフォルダーを開くとき、Windows Server 2012のクライアント リダイレクターは 2 つの SMB パケットを送信します。 1 つのパケットは "作成" パケットで、もう 1 つは "クエリ ディレクトリ" パケットです。 作成パケットはディレクトリを開き、クエリ ディレクトリ パケットを使用すると、リダイレクターはサブフォルダーに関する情報を特定して、サブフォルダーを正しく処理できます。 パケットの作成は、STATUS_ACCESS_DENIEDで失敗します。 ただし、その後、クエリ ディレクトリ パケットもSTATUS_UNEXPECTED_NETWORK_ERRORで失敗します。 そのため、2 つのエラー コードがあります。 クエリ ディレクトリ アクションは作成後に発生したため、クエリ ディレクトリ エラー コードが返されます。
ERROR_ACCESS_DENIEDが返されるように Windows の設計が変更された場合でも、サーバーのクラッシュ、ネットワーク電源の損失など、実際のネットワーク エラーが発生する可能性があるため、ネットワーク共有にアクセスするアプリケーションは引き続きERROR_UNEXP_NET_ERRを受け取る可能性があります。
また、ローカル ドライブへの I/O とネットワーク ファイル共有への I/O には違いがあることにも注意してください。 アプリケーションで使用される API (CreateFile、ReadFile、FindFirstFile など) はすべて同じですが、作業を行うストレージ システムは異なります。 アプリケーションがローカル ファイルにアクセスすると、API によって IRP が作成され、ファイル システム ドライバー (NTFS.SYS) に送信され、最終的に I/O 要求がディスク ドライバーに送信されます。 アプリケーションがネットワーク共有にアクセスすると、API によってクライアント/サーバー ネットワーク プロトコルが呼び出されます。 API は要求をクライアント リダイレクターに送信し、クライアント リダイレクターによって SMB パケットが作成され、SMB パケットがサーバーに送信されます。 サーバーのサービスがパケットを受信し、I/O 操作を実行します。 I/O 操作が完了すると、サーバーのサービスは応答 SMB パケットをクライアント リダイレクターに送信し、クライアント リダイレクターはアプリケーションに戻ります。
これらの違いにより、API はさまざまな種類のエラーを返すことができます。 ローカル ファイルの場合、API はネットワーク エラーを返しません。 ネットワーク ファイルの場合、API は、ネットワーク上で発生する可能性があるため、ERROR_ACCESS_DENIEDやERROR_UNEXP_NET_ERRなどのネットワーク エラーなどのファイル アクセス エラーを返すことができます。 この動作は設計上のものであり、次の 2 つの場所にある Microsoft Developer Network (MSDN) ライブラリに記載されています。
フィードバック
https://aka.ms/ContentUserFeedback。
近日公開予定: 2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub イシューを段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、以下を参照してください:フィードバックの送信と表示