それ以外の環境に違いがあるんでしょう?
ご自身でも書かれたように情報不足です。
再現手順なり、最低限のコードなりを提示していただかないと
我々はエスパーではありませんので…
「システムコールに渡されるデータ領域が小さすぎます。」の間違いでは?
RAPTさん、ありがとうございます。
ご指摘通りです。
エラー発生箇所と思われる部分が間違っていました。すみません。
以下のコードのEnumPortsの結果がエラーのようです。
EnumPortsがエラーを返す理由についてはまだわかりません。
BOOL Commctrl::CheckPort()
{
/* シリアルポート検査 */
PORT_INFO_1 pi1[sizeof(PORT_INFO_1) * ENUMPORT];
DWORD dwNeed = 0, dwRet = 0, dw;
int i, port_count = 0;
if ( !EnumPorts(NULL, 1, (unsigned char *)&pi1, sizeof(pi1), &dwNeed,
&dwRet) )
{
ErrMsg();
return FALSE;
}
for(dw = 0, i = 0; dw < dwRet; dw++)
{
TRACE(port Name = %s\n, pi1[dw].pName);
if ( memcmp(pi1[dw].pName, COM, 3) == 0 )
{
/* delete はデストラクタにて行なうので大丈夫なはず・・・!? */
CString *str = new CString;
str->Format(%s, pi1[dw].pName);
str->Delete(str->Find(:), 1);
*(strPortName + i) = str;
i++;
}
}
iPort_num = i;
return Open_Port(ptset.iPort_Index);
}
> if ( !EnumPorts(NULL, 1, (unsigned char *)&pi1, sizeof(pi1), &dwNeed,
&dwRet) )
> {
> ErrMsg();
> return FALSE;
> }
単にdwNeedがsizeof(pi1)より大きいだけでしょ。
エラー判定するならちゃんとGetLastErrorでERROR_INSUFFICIENT_BUFFERをハンドリング
しなきゃ。
一発目で失敗してERROR_INSUFFICIENT_BUFFERが返ってきたらdwNeedバイト分領域を確保
して
もう一度EnumPortsすれば大丈夫でしょ。
> EnumPortsがエラーを返す理由についてはまだわかりません。
MSDNより
> pcbNeeded
> プリンタポートを列挙するデータのサイズ (バイト数) を受け取る変数へのポイン
> タを指定します。cbBuf がこの値より小さいと EnumPorts は失敗しGetLastError
> 関数が ERROR_INSUFFICIENT_BUFFER を返し、pcbNeeded が指すデータは必要なバッ
> ファサイズを表します。cbBuf がこの値と等しいかこの値より大きいと、cbNeeded
> が指す変数はバッファに格納されたバイト数を表します。
とあります。
一応ここは、2段回でEnumPortsをよんだほうがよさそう。
#include <windows.h>
#include <iostream>
int main()
{
DWORD dwNeed, dwRet;
BYTE* buff;
PORT_INFO_1* pi1;
::EnumPorts( NULL, 1, NULL, 0, &dwNeed, &dwRet );
buff = new BYTE[ dwNeed ];
if ( ::EnumPorts( NULL, 1, buff, dwNeed, &dwNeed, &dwRet ) )
{
pi1 = ( PORT_INFO_1* )buff;
for ( int i = 0; i < dwRet; i++ )
{
std::cout << pi1[ i ].pName << std::endl;
}
}
delete[] buff;
return 0;
}
ついでに
> if ( memcmp(pi1[dw].pName, COM, 3) == 0 )
は
strncmpの方が最適かも。(意味合い的に)
> *(strPortName + i) = str;
これって、strPortName は CString* 型の配列でしょうか?
CStringArrayを利用すると、メモリを気にせずに扱えますよ。
> CString *str = new CString;
>
> str->Format(%s, pi1[dw].pName);
> str->Delete(str->Find(:), 1);
> *(strPortName + i) = str;
// コンストラクタで文字列を設定できる
CString str( pi1[ dw ].pName );
// : が1つしかでてこないならReplaceを使ってみるとか
str.Replace( _T( : ), _T( " ) );
// strPortNames が CStringArray型 のメンバ変数だと便利
strPortNames.Add( str );
kureさん、Blueさん
教えて頂いた方法で修正したところ、上手くいくようになりました。
今後はもう少しエラー発生箇所をしっかり絞り込めるようにしたいと思います。
親切・丁寧なご指導ありがとうございました。