在带有 WM_COPYDATA 消息的结构中使用 LPCTSTR 是否安全?
Is it safe to use LPCTSTR in a structure with the WM_COPYDATA message?
我有这样的结构:
typedef struct tagCOPY_PACKET
{
TCHAR szFile[_MAX_PATH];
GUID guidSignature;
} S_COPY_PACKET;
我准备像这样用 WM_COPYDATA
发送数据:
CString strFile = GetFileToOpenFromFileExplorerPath();
S_COPY_PACKET sCopyDataPacket;
_tcscpy_s(sCopyDataPacket.szFile, _MAX_PATH, strFile);
sCopyDataPacket.guidSignature = CopyData_Signature;
COPYDATASTRUCT cds;
cds.dwData = COPYDATA_TYPE_MSA;
cds.cbData = sizeof(sCopyDataPacket);
cds.lpData = &sCopyDataPacket;
DWORD_PTR dwResult;
if (SendMessageTimeout(hOtherInstance, WM_COPYDATA,
NULL, (LPARAM)(LPVOID)&cds, SMTO_BLOCK, 2000, &dwResult) != 0)
{
}
在另一端:
BOOL CMeetingScheduleAssistantDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
if (pCopyDataStruct->dwData == COPYDATA_TYPE_MSA)
{
S_COPY_PACKET* pCopyPacket = (S_COPY_PACKET*)(pCopyDataStruct->lpData);
if (pCopyPacket->guidSignature != CopyData_Signature)
{
// Bad GUID
return FALSE;
}
if (GetLastActivePopup() != this) // Popup windows!
{
// TODO: Tell user?
return FALSE;
}
theApp.SetFileToOpenFromFileExplorer(pCopyPacket->szFile);
OpenFileFromFileExplorer();
return TRUE;
}
return FALSE;
}
它工作正常。我只是想知道像这样更改我的结构是否可以接受:
typedef struct tagCOPY_PACKET
{
LPCTSTR lpszFile;
GUID guidSignature;
} S_COPY_PACKET;
然后使用:
S_COPY_PACKET sCopyDataPacket;
sCopyDataPacket.lpszFile = strFile.GetBufferSetLength(_MAX_PATH);
sCopyDataPacket.guidSignature = CopyData_Signature;
COPYDATASTRUCT cds;
cds.dwData = COPYDATA_TYPE_MSA;
cds.cbData = sizeof(sCopyDataPacket);
cds.lpData = &sCopyDataPacket;
...
并且,在发布和处理消息后:
strFile.ReleaseBuffer();
将 LPCTSTR
方法与 WM_COPYDATA
一起使用是否安全,如果是,为什么?
没有。 LPCTSTR
是一个指针。因此接收方应用程序将收到指向发送方应用程序内存位置的指针。如果接收方应用程序尝试访问数据,它会导致接收方应用程序因内存冲突而崩溃。
documentation of WM_COPYDATA
说:
The data being passed must not contain pointers or other references to objects not accessible to the application receiving the data.
因此,当 CMeetingScheduleAssistantDlg
存在于不同的可执行文件中时,您无法传递 LPCTSTR
值。如果它在同一个可执行文件中,它很可能会起作用。
我有这样的结构:
typedef struct tagCOPY_PACKET
{
TCHAR szFile[_MAX_PATH];
GUID guidSignature;
} S_COPY_PACKET;
我准备像这样用 WM_COPYDATA
发送数据:
CString strFile = GetFileToOpenFromFileExplorerPath();
S_COPY_PACKET sCopyDataPacket;
_tcscpy_s(sCopyDataPacket.szFile, _MAX_PATH, strFile);
sCopyDataPacket.guidSignature = CopyData_Signature;
COPYDATASTRUCT cds;
cds.dwData = COPYDATA_TYPE_MSA;
cds.cbData = sizeof(sCopyDataPacket);
cds.lpData = &sCopyDataPacket;
DWORD_PTR dwResult;
if (SendMessageTimeout(hOtherInstance, WM_COPYDATA,
NULL, (LPARAM)(LPVOID)&cds, SMTO_BLOCK, 2000, &dwResult) != 0)
{
}
在另一端:
BOOL CMeetingScheduleAssistantDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
if (pCopyDataStruct->dwData == COPYDATA_TYPE_MSA)
{
S_COPY_PACKET* pCopyPacket = (S_COPY_PACKET*)(pCopyDataStruct->lpData);
if (pCopyPacket->guidSignature != CopyData_Signature)
{
// Bad GUID
return FALSE;
}
if (GetLastActivePopup() != this) // Popup windows!
{
// TODO: Tell user?
return FALSE;
}
theApp.SetFileToOpenFromFileExplorer(pCopyPacket->szFile);
OpenFileFromFileExplorer();
return TRUE;
}
return FALSE;
}
它工作正常。我只是想知道像这样更改我的结构是否可以接受:
typedef struct tagCOPY_PACKET
{
LPCTSTR lpszFile;
GUID guidSignature;
} S_COPY_PACKET;
然后使用:
S_COPY_PACKET sCopyDataPacket;
sCopyDataPacket.lpszFile = strFile.GetBufferSetLength(_MAX_PATH);
sCopyDataPacket.guidSignature = CopyData_Signature;
COPYDATASTRUCT cds;
cds.dwData = COPYDATA_TYPE_MSA;
cds.cbData = sizeof(sCopyDataPacket);
cds.lpData = &sCopyDataPacket;
...
并且,在发布和处理消息后:
strFile.ReleaseBuffer();
将 LPCTSTR
方法与 WM_COPYDATA
一起使用是否安全,如果是,为什么?
没有。 LPCTSTR
是一个指针。因此接收方应用程序将收到指向发送方应用程序内存位置的指针。如果接收方应用程序尝试访问数据,它会导致接收方应用程序因内存冲突而崩溃。
documentation of WM_COPYDATA
说:
The data being passed must not contain pointers or other references to objects not accessible to the application receiving the data.
因此,当 CMeetingScheduleAssistantDlg
存在于不同的可执行文件中时,您无法传递 LPCTSTR
值。如果它在同一个可执行文件中,它很可能会起作用。