GetIDsFromNames() fails when STRING name of 'NAMED Propertty' is used - outlook

I am using MAPI MSG file as message source. From this message I am unable to fetch named-property using property-name. GetIDsFromNames() works when I pass ID. Please see the sample below.
const GUID PSETID_Common1 = {0x00062008, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}};
MAPINAMEID Mon1;
LPMAPINAMEID Mon1_id = &Mon1;
Mon1_id->lpguid = &PSETID_Common1;
if(useID == 0)
{ //In this case GetIDsFromNames() fails
Mon1_id->ulKind = MNID_STRING;
Mon1_id->Kind.lpwstrName = L"PidTagInternetAccountName";
}
else
{ //In this case GetIDsFromNames() succeeds
Mon1_id->ulKind = MNID_ID;
Mon1_id->Kind.lID = useID;
}
hr = obj->GetIDsFromNames(1, &Mon1_id, 0, &cols);
I tried using these names: dispidInetAcctName, PidTagInternetAccountName, PidNameInternetAccountName
Is GetIDsFromNames() failing because MSG lacks the information required to convert NAME->ID. I think this information is stored on EX server.

What is the actual value of hr? If the mapping does not exist yet for that particular MSG file, you must pass the MAPI_CREATE flag when calling GetIDsFromNames.

Related

anyone using IXCLRDataProcess, GetRuntimeNameByAddress and ICLRDataTarget to get managed symbol?

the purpose is to get a mixed callstack. For managed symbol, I use IXCLRDATAProcess / GetRuntimeNameByAddress to resolve the corresponding managed callstack. I modify this project to get self-mixed callstack, it works on X86, but it failed on X64. after debugging, I find the issue is located in IXCLRDATAProcess. Our project is located in this.
this is my way to use IXCLRDATAProcess:
HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
void** iface;
BOOL isWow64 = FALSE;
if (processHandle == NULL)
return NULL;
BOOLEAN result = IsWow64Process(processHandle, &isWow64);
DiagCLRDataTarget* dataTarget = new DiagCLRDataTarget(ProcessId, processHandle, isWow64, debugNative); //new DnCLRDataTarget;
ICLRDataTarget* target = static_cast<ICLRDataTarget*>(dataTarget);
HMODULE accessDll = LoadLibraryW(L"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\mscordacwks.dll");
PFN_CLRDataCreateInstance entry = (PFN_CLRDataCreateInstance)GetProcAddress(accessDll, "CLRDataCreateInstance");
hr = entry(__uuidof(IXCLRDataProcess), target, (void**)&ifacePtr); // error
if (FAILED(hr)) {
std::cout << "error: " << GetLastError() << std::endl; // where we get error: 203:230 (0xE6) The pipe state is invalid.
*iface = ifacePtr;
}
m_clrDataProcess = static_cast<IXCLRDataProcess*>(iface);
then I use m_clrDataProcess to resolve the symbol, that is
hr = m_clrDataProcess->GetRuntimeNameByAddress(clrAddr, 0, maxSize - 1, &nameLen, buffer, &displacement);
due to the m_clrDataProcess being null, we can't resolve symbol from the frame address. Does anyone use these API or does anyone have some advice?

Blue screen when rewriting packets at DATAGRAM_DATA layer in WFP

I've been trying to modify outgoing DNS packets via the DATAGRAM_DATA layer in WFP, however i get blue screen errors when rewriting the destination ip in the outgoing packet. What am i doing wrong?
I admit i found the parameters for FwpsInjectTransportSendAsync a bit confusing, and was unsure exactly what to put in for the sendParams arg - though i think what i have looks right.
RtlIpv4StringToAddressExW(
L"1.1.1.1", // hard-coding the new (rewritten) dns server for now
FALSE,
&sin4.sin_addr,
&sin4.sin_port);
RtlIpv4StringToAddressExW(
L"8.8.8.8", // hard-coding the original dns server for now
FALSE,
&origSin4.sin_addr,
&origSin4.sin_port);
if ((Direction == FWP_DIRECTION_OUTBOUND) && (PacketInjectionState == FWPS_PACKET_NOT_INJECTED) && (RemotePort == 53) && (RemoteAddress == origSin4.sin_addr.S_un.S_addr))
{
UINT32 IpHeaderSize = inMetaValues->ipHeaderSize;
UINT32 TransportHeaderSize = inMetaValues->transportHeaderSize;
UINT64 endpointHandle = inMetaValues->transportEndpointHandle;
PNET_BUFFER NetBuffer = NET_BUFFER_LIST_FIRST_NB((PNET_BUFFER_LIST)layerData);
NdisRetreatNetBufferDataStart(NetBuffer, IpHeaderSize + TransportHeaderSize, 0, NULL);
PNET_BUFFER_LIST NetBufferList = NULL;
NTSTATUS Status = FwpsAllocateCloneNetBufferList(layerData, NULL, NULL, 0, &NetBufferList);
if (!NT_SUCCESS(Status))
{
return;
}
NdisAdvanceNetBufferDataStart(NetBuffer, IpHeaderSize + TransportHeaderSize, FALSE, NULL);
if (!NetBufferList)
{
return;
}
NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
PIPV4_HEADER IpHeader = NdisGetDataBuffer(NetBuffer, sizeof(IPV4_HEADER), NULL, 1, 0);
// Rewriting the dest ip
IpHeader->DestinationAddress = sin4.sin_addr.S_un.S_addr;
// Updating the IP checksum
UpdateIpv4HeaderChecksum(IpHeader, sizeof(IPV4_HEADER));
// not 100% sure the sendParams argument is setup correctly, the docs are slightly unclear
FWPS_TRANSPORT_SEND_PARAMS sendParams = {
.remoteAddress = (UCHAR*)IpHeader->DestinationAddress,
.remoteScopeId = inMetaValues->remoteScopeId,
.controlData = inMetaValues->controlData,
.controlDataLength = inMetaValues->controlDataLength,
.headerIncludeHeader = inMetaValues->headerIncludeHeader,
.headerIncludeHeaderLength = inMetaValues->headerIncludeHeaderLength
};
Status = FwpsInjectTransportSendAsync(g_InjectionHandle, NULL, endpointHandle, 0, &sendParams, AF_INET, inMetaValues->compartmentId, NetBufferList, DriverDatagramDataInjectComplete, NULL);
if (!NT_SUCCESS(Status))
{
FwpsFreeCloneNetBufferList(NetBufferList, 0);
}
classifyOut->actionType = FWP_ACTION_BLOCK;
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;
}
Two things stand out to me, both in the sendParams.
First, remoteAddress is incorrect. It needs to a pointer to the address, so it should be (UCHAR*)&IpHeader->DestinationAddress.
Second, FwpsInjectTransportSendAsync() is asynchronous so any parameters you pass to it need to stay valid until it completes which may be after your calling function returns. Typically you allocate some context structure that contains sendParams and deep copies of relevant members (remoteAddress and controlData). You pass this as the context to the completion routine where you free it.

Passing a variable value to a list box from a database table

I am trying to populate a listbox with IDs. While the planned functionality is that once the user clicks on an ID, it fills the edit controls with appropriate data from that ID's row. Problem is, I can't find to actually fill the listbox. It refuses to take strings (but I can write them manually), it refuses integers. Arrrgh! I tried conversion, like in this code snippet, i tried just giving it an integer (then it compiles but crashes)
case WM_INITDIALOG:
{
int i = 1;
res = stmt->executeQuery("SELECT id FROM tremreg");
while (res->next())
{
std::string str = boost::lexical_cast<std::string>(i);
SendDlgItemMessage(hwnd, IDC_lbList, LB_ADDSTRING, 0, (LPARAM)str);
i++;
}
}
break;
This won't work either:
case WM_INITDIALOG:
{
res = stmt->executeQuery("SELECT id FROM tremreg");
while (res->next())
{
SendDlgItemMessage(hwnd, IDC_lbList, LB_ADDSTRING, 0, (LPARAM)res->getString("ID);
}
}
break;
How do you pass it a goddamn VARIABLE?

Search by artist using libspotify on windows?

The api is very poorly documented and I am very confused. The method sp_search takes parameters (sp_search* search, int index). How do I create an sp_search object?
Full documentation for libspotify can be found here. Search functions are under "Modules" then "Search".
The spshell example that comes with libspotify contains a full implementation of search in the search.c file. It's done like this:
sp_search *newSearch = sp_search_create(session,
"foo fighters", //query
0, // track_offset
100, //track_count
0, //album_offset
100, //album_count
0, //artist_offset
100, //artist_count
0, // playlist_offset,
100, // playlist_count
SP_SEARCH_STANDARD, // search type
&search_complete, //callback
NULL); // userdata
void search_complete(sp_search *result, void *userdata) {
int trackCount = sp_search_num_tracks(search);
for (int currentTrack = 0; currentTrack < trackCount; currentTrack++) {
sp_track *track = sp_search_track(search, currentTrack);
// Do something with track...
}
}

Determining the default message store under Windows Mobile

The following piece of test code runs under Windows Mobile.
It's objective is to seek out the default message store so I can get the proper account name for programmatically compiling an email.
IMAPISession *mapiSession;
HRESULT hr = S_OK;
MAPIInitialize (NULL);
IMAPITable *msgTable;
SRowSet *pRows;
IMsgStore *msgStore;
if (MAPILogonEx(0,NULL,NULL,0,&mapiSession) != S_OK)
{
// MessageBox(g_hWnd,_T("Failed to logon"),_T("Error"),0);
}
else
{
SizedSPropTagArray(3, PropTagArr) = {3,{PR_DISPLAY_NAME,
PR_ENTRYID,
PR_DEFAULT_STORE}};
hr = mapiSession->GetMsgStoresTable(MAPI_UNICODE,&msgTable);
hr = msgTable->SetColumns((LPSPropTagArray)&PropTagArr, 0);
if (!hr)
{
do
{
hr = msgTable->QueryRows(1,0,&pRows);
LPSPropValue lpProp;
lpProp = &pRows->aRow[0].lpProps[0];
// if(_tcscmp( lpProp->Value.LPSZ, _T("SMS") ) == 0 )
// break;
lpProp = &pRows->aRow[0].lpProps[0];
if (lpProp->ulPropTag == PR_DEFAULT_STORE)
break;
lpProp = &pRows->aRow[0].lpProps[1];
if (lpProp->ulPropTag == PR_DEFAULT_STORE)
break;
lpProp = &pRows->aRow[0].lpProps[2];
if (lpProp->ulPropTag == PR_DEFAULT_STORE)
break;
FreeProws(pRows);
pRows = NULL;
}while (!hr);
hr = mapiSession->OpenMsgStore (0,
pRows->aRow[0].lpProps[1].Value.bin.cb,
(ENTRYID*)pRows->aRow[0].lpProps[1].Value.bin.lpb,
NULL,
MDB_NO_DIALOG | MAPI_BEST_ACCESS,
&msgStore);
... BUT, fails to get the PR_DEFAULT_STORE property on a Windows Mobile device. I'm guessing Microsoft didn't implement it accurately. And so, lpProp->ulPropTag will never == PR_DEFAULT_STORE. It's always 0000.
Has anyone had success getting PR_DEFAULT_STORE using MAPI under Windows Mobile?
Is there another way of the determining the default message store?

Resources