'outlook profile .PST and .OST file location using MAPI in delphi

anyone tell that how to find .PST and .OST file location for particular profile using MAPI in Delphi?

Code:

I have written the below code to find the .PST path. But I am getting the error "2147221233" in the line "HrgetoneProps"

 FMapiSession := nil;
  res := MAPILogonEx(0, 'Default Outlook Profile', nil, ulFlags, FMapiSession);
if res = S_OK then
  begin
    res := MAPIAdminProfiles(0, ProfAdmin);
    {$IFDEF DEBUG}CodeSite.Send('MAPIAdminProfiles'); {$ENDIF}
    if res = S_OK then
      begin
        res := FMapiSession.AdminServices(0, ServAdmin);
        if res = S_OK then
          begin
            res := ServAdmin.GetMsgServiceTable(0, Tbl);
            if res = S_OK then
              begin
                res := Tbl.SetColumns(PSPropTagArray(@sptCols), 0);
                if res = S_OK then
                  begin
                    sres.rt := RES_PROPERTY;
                    sres.res.resProperty.relop := RELOP_EQ;
                    sres.res.resProperty.ulPropTag := PR_SERVICE_NAME;
                    sres.res.resProperty.lpProp := @spv;
                    spv.ulPropTag := PR_SERVICE_NAME;
                    spv.Value.lpszA := 'MSUPST MS';
                    res := HrQueryAllRows(Tbl, @sptCols, @sres, nil, 0, pRow);
                    if res = S_OK then
                      begin
                        for I := 0 to pRow.aRow[0].cValues - 1 do
                          begin
                            if (pRow.aRow[0].lpProps[I].ulPropTag = PR_SERVICE_UID) then
                              begin
                                MsgStoreUID := PMAPIUID(pRow.aRow[0].lpProps[I].Value.bin.lpb);
                                break;
                              end;
                          end;
                        res := ServAdmin.OpenProfileSection(MsgStoreUID, TGUID(nil^),
                          MAPI_Force_ACCESS or MAPI_MODIFY, ProfSect);

                        if res = S_OK then
                          begin
                            {$IFDEF DEBUG}CodeSite.Send('HrGetOneProp'); {$ENDIF}
                            res := HrGetOneProp(ProfSect, PR_PST_PATH, propVal);
                            if res = S_OK then
                              begin
                                Result := propVal^.Value.lpszA;
                                MAPIFreeBuffer(propVal);
                              end
                          end
                        else
                          begin
                            // ...
                          end;
                        FreePRows(pRow);
                      end;
                  end;
              end;
          end;
      end;
  end


Solution 1:[1]

You can either

  1. parse the store entry id: its format is documented on MSDN - take a look at PR_STORE_ENTRYID in OutlookSpy (I am its author).

  2. Look at all service providers in the profile (IMsgServiceAdmin.GetMsgServiceTable). For the services with PR_SERVICE_NAME == 'MSPST MS' / 'MSUPST MS'/ 'INTERSTOR', etc., read the table of the service providers (IMsgServiceAdmin.AdminProviders), open profile section, read PR_ENTRYID. Use IMAPISession::CompareEntryIDs to compare that entry id with the entry id of the store in question. If they match, read PR_PST_PATH property. You can play with this in OutlookSpy - click IMAPISession | AdminServices.

  3. Use Redemption (I am also its author) - it exposes RDOPstStore.PstPath and RDOExchangeStore.OstPath.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1