不明な長さのデータの取得

多くの関数は、アプリケーションによってパラメーターの 1 つとして指定されたアドレスに大量のデータを返す可能性があります。 これらのすべての場合、操作は、同一ではない場合でも同様の方法で実行されます。 返されるデータの場所をポイントするパラメーターは、pb または pv がパラメーター名の最初の 2 文字である表記規則を使用します。 別のパラメーターには、パラメーター名の最初の 3 文字として、もう 1 つのパラメーターが含まれています。 このパラメーターは、pb または pv の場所に返されるデータのサイズをバイト単位で表します。 たとえば、次の関数の仕様を考え考え考えしてください。

#include <windows.h>

BOOL WINAPI SomeFunction(
  PCCRL_CONTEXT pCrlContext,  // in
  DWORD dwPropId,             // in
  BYTE *pbData,               // out
  DWORD *pcbData              // in/out
);

この例では 、pbData はデータが返される場所へのポインターであり 、pbData は返されるデータのサイズ (バイト単位) です。

注意

場合によっては、pv パラメーターのコンパニオン パラメーターに、p や pv などの若干異なるプレフィックスを指定できます。 また、プレフィックス pwsz と pcch の組み合わせを使用するコンパニオン パラメーターの場合、pcch パラメーターは、返されるデータの文字数 (Unicode または ASCII)です (該当する場合)。

pbData パラメーターで指定されたバッファーが、返されたデータを保持するのに十分な大きさではない場合、関数は ERROR MORE DATA コード (GetLastError 関数を呼び出すことによって確認できます) を設定し、必要なバッファー サイズ (バイト単位) を _ _ 、この変数に格納します。

null pbData に対して入力され、この場合、エラー は返されません。また、関数は、必要なメモリ バッファーのサイズ (バイト単位) を 、この変数のサイズを返します。 これにより、アプリケーションは、返されるデータのバッファーのサイズと、割り当てに最適な方法を決定できます。

注意

返されたデータが指定されたバッファーに収まるかどうかを確認するために必要なサイズを決定するために pbDataNULL が入力されている場合、目的のデータをバッファーに設定する関数の 2 番目の呼び出しでは、バッファー全体が使用されない可能性があります。 2 回目の呼び出しの後、返されるデータの実際のサイズは 、このデータのサイズは、"数" の "データ" に格納されます。 このサイズは、データの処理時に使用します。

次の例は、この目的のために入力パラメーターと出力パラメーターを実装する方法を示しています。

//-------------------------------------------------------------------
// Copyright (C) Microsoft.  All rights reserved.
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

void MyHandleError(char *s);

void main()
{

// Set up SomeFunction variables.
PCCRL_CONTEXT pCrlContext; // Initialized elsewhere.
DWORD dwPropId;            // Initialized elsewhere.
DWORD cbData;
BYTE  *pbData;

// Call SomeFunction to set cbData, the size of 
// the buffer needed for pbData.
if(SomeFunction(
     pCrlContext, 
     dwPropId, 
     NULL, 
     &cbData))
{
       printf("The function succeeded.\n");
}
else
{

// The function call failed. Handle the error.
       MyHandleError("Function call failed.");
}

// The call succeeded; the size for the needed buffer, in bytes, 
// now resides in cbData.

// Malloc memory for the size of the message.
if(pbData = (BYTE*)malloc(cbData))
{
   printf("Memory has been allocated.\n");
}
else
{

   // The allocation failed. Write an error message and exit.
   MyHandleError("Malloc operation failed. ");
}

// The space for the buffer has been allocated.
// Call SomeFunction to fill the buffer with the data.
if(SomeFunction(
      pCrlContext, 
      dwPropId, 
      pbData, 
      &cbData))
{
       printf("The function succeeded.\n");
}
else
{

   // The second function call failed. Handle the error.
   MyHandleError("The second call to the function failed.");
}

// The function succeeded; the data is now in the buffer
// pointed to by pbData. Note that cbData is
// updated with the actual size of the data returned. Use this size 
// to process bytes of pbData.

// When you have finished using the allocated memory, free it.
free(pbData);

} // End of main

//  This example uses the function MyHandleError, a simple error
//  handling function, to print an error message to the 
//  standard error (stderr) file and exit the program. 
//  For most applications, replace this function with one 
//  that does more extensive error reporting.
void MyHandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program.\n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr,"Error number %x.\n",GetLastError());
    fprintf(stderr,"Program terminating.\n");
    exit(1);
}