InstallShield calling advapi32.dll method type mismatch error - installshield

I am trying to call Advapi32.LsaOpenPolicy() from basic MSI InstallShield code. I've successfully called other avdapi32.dll methods; But LsaOPenPolicy is throwing a mismatched type error.
My prototype is:
prototype INT Advapi32.LsaOpenPolicy(POINTER, POINTER, INT, POINTER);
The windows definition is:
NTSTATUS LsaOpenPolicy(
_In_ PLSA_UNICODE_STRING SystemName,
_In_ PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
_In_ ACCESS_MASK DesiredAccess,
_Inout_ PLSA_HANDLE PolicyHandle
);
I've noted in C++ samples that the ObjectAttriibute structure is zeroed out. So I do something similar here in the InstallShield code -- pArray points to the array contents.
for i = 0 to 11
array(i) = 0;
endfor;
array(0) = 24;
// current error is 80020005 type mismatch.
try
i = POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES;
pArray = array;
pPolicy = NULL;
nvOSResult = LsaOpenPolicy(NULL, pArray, i, pPolicy);
catch
Sprintf(errString, "0x%08x", Err.Number);
_Logger(hMSI, methodName, "LsaOpenPolicy Exception "+errString, INFORMATION, FALSE);
nvOSResult = Err.Number;
endcatch;
There not much other information I can find other than the 80020005 error thrown; I've tried a few different argument constructions, but I can't get past this.
I've posted this in an flexera and microsoft forum -- but I have gotten no traction there. (references for posterity: flexera-link, microsoft-link)
Any help or suggestions are welcome!

The answer to this question was to actually work-around the interface between installshield and the system DLLs by moving all the workings into a C++ DLL. As installation got more complex, I ended up with two separate DLL functions, one executed at dialog (non-admin) mode and one at deferred execution (admin) mode.
In order to pass information I used the MsiGetProperty() API using MSI properties for both input and output variables.
Note that for deferred execution, I needed a CAD function on the installshield side to marshal data into the custom action data location, and on the DLL side extract the data, again by using MsiGetProperty() but getting the "CustomActionData" property and then parse the resulting string which contained the marshaled data.

Related

Microsoft Excel has stopped working

Whenever I use the arrow key to scroll down, Excel stops working:
And I get this:
To quickly rule out problems with excel itself, type in run dialog (Winkey + R) - excel /a. This starts excel for COM and means no customisation of excel. Does your error occur now.
Get the error details. In settings search for View Problem Details. Right click your error and choose View Technical Details. Post those here.
It will look something like this.
Description
A problem caused this program to stop interacting with Windows.
Faulting Application Path: C:\Program Files\Internet Explorer\iexplore.exe
Problem signature
Problem Event Name: AppHangXProcB1
Application Name: iexplore.exe
Application Version: 11.0.10240.16412
Application Timestamp: 55b99d3f
Hang Signature: d229
Hang Type: 134742048
Waiting on Application Name: iexplore.exe
Waiting on Application Version: 11.0.10240.16412
OS Version: 10.0.10240.2.0.0.768.101
Locale ID: 3081
Additional Hang Signature 1: d2293b30a82e02c1d065885655e2fc11
Additional Hang Signature 2: e68d
Additional Hang Signature 3: e68d7530cc359e253127575d50ba30e2
Additional Hang Signature 4: d229
Additional Hang Signature 5: d2293b30a82e02c1d065885655e2fc11
Additional Hang Signature 6: e68d
Additional Hang Signature 7: e68d7530cc359e253127575d50ba30e2
Decoding Errors
-2147220978 style numbers are 32 bit signed integers, convert to hex =
with calculator.
Windows errors (smallish numbers) and COM HResults (typically, but with =
exceptions, start with an 8 as in 0x80040154) are defined in WinError.h, =
except 8007nnnn where you look up the Window error number that it =
contains.
As a general rule Windows errors are less than 65,535 (0xFFFF). Errors =
starting 0x80000001 are Component Object Model (COM) HResults. Errors =
starting 0xC0000001 are NTStatus results. Errors starting 0xD0000001 are =
also NTStatus values returned in a HResult.
NTStatus errors (typically but not always start with an C as in =
0xC0000022) are defined in NTStatus.h.=20
.h files are the best source because it includes the symbolic name of =
the error which can give clues such as the source of the error. =
FormatMessage doesn't give the symbolic name only the description.
You get these files by downloading the Platform SDK (it's gigabytes)
http://www.microsoft.com/en-us/download/details.aspx%3Fid%3D8279&sa=3DU&e=
i=3Dw2IrULDDLsHFmAWbmIHoBg&ved=3D0CBwQFjAA&usg=3DAFQjCNHZn9-4f2NnuN9o3UWU=
sOF3wL7HBQ
If you just want the two files I have them on my skydrive so I can =
reference them anywhere I go.
https://skydrive.live.com/redir?resid=3DE2F0CE17A268A4FA!121
Note internet errors (12,000 - 12,999) are windows errors but are =
specified in wininet.h also available above.=20
There are errors defined in other .h files. But 99% are in the three =
above.
Structure of HResults and NTStatus Codes
The most significant bit in HResults, and the two most significant bits =
in NTStatus are set on error. Hence Hresults start 8 on error and =
NTStatus starts C on Error. The next 14 or 15 bits are reserved and some =
specify the facility - what area the error is in. This is the third and =
fourth number when reading hex. EG 0xnn07nnnn - An HResult facility code =
7 is a normal Windows' error (returned from a COM program - hence it's =
returned as a HResult). Facility codes are defined in Winerror.h for =
HResults and NTStatus.h for NTStatus codes. They are different.
To Decode 0x8003nnnn Errors
HResults with facility code 3 means the HResult contains OLE Structured =
Storage errors (0x0 to 0xff). These are the same as Dos error codes. =
These don't seem to be in Windows' header files and the list of codes is =
at the end of this post.
To Decode 0x8004nnnn Errors
HResults with facility code 4 means the HResult contains OLE errors (0x0 =
to 0x1ff) while the rest of the range (0x200 onwards) is component =
specific errors so 20e from one component will have a different meaning =
to 20e from another component.
This is why the source of the error is extra important for errors above =
0x80040200.
To Decode 0x8007nnnn Errors
HResults with facility code 7 means the HResult contains a Windows' =
error code. You have to look up the Windows' error code not the HResult.
To decode 0x80070002. The 0x means it's a hexadecimal number, the 8 =
means error, the first 7 means it a windows error, and the rest of the =
number, 2, is the actual Windows error.
To look up the error we need it in decimal format. Start Calculator =
(Start - All Programs - Accessories - Calculator) and choose View menu - =
Scientific, then View menu - Hex. Enter 2. Then View menu - Decimal. It =
will say 2.
Start a Command Prompt (Start - All Programs - Accessories - Command =
Prompt) and type
net helpmsg 2
and it will say
The system cannot find the file specified.
or look it up in winerror.h
//
// MessageId: ERROR_FILE_NOT_FOUND
//
// MessageText:
//
// The system cannot find the file specified.
//
#define ERROR_FILE_NOT_FOUND 2L
To Decode 0x8019nnnn Errors
HResults with facility 0x19 are HTTP errors. Codes under 16,384 (0x4000) =
are the same as HTTP errors, eg HTTP status 404: The requested URL does =
not exist on the server is 0x80190194 (0x194 =3D 404). Codes 16,384 and =
higher are BITS specific.
To Decode 0xDnnnnnnn Errors
HResults starting 0xD are an HResult with a NTStatus value in it. Just =
cange the lead D to a C and treat as an NTStatus (Hresult =3D NTStatus =
OR 10000000).

Cairo.Surface is leaking... How to debug it with Monodevelop?

I have many doubts related with Cairo and GTK# (that runs on .NET and Mono). I'm developing a GTK# application for MS Windows and Linux. I'm using GTK# 2.12 over .NET right now while I'm working on the application.
I've created a custom widget that uses Cairo.ImageSurface and Cairo.Context objects. As far as I know, I'm calling the Dispose method of every ImageSurface object and every Context object I create inside the widget code.
The widget responds to the "MouseOver" event, redrawing some parts of its DrawingArea.
The (first) problem:
almost every redrawing operation increases a little bit the amount of used memory. When the amount of used memory has increased 3 or 4 Kbytes the Monodevelop tracelog panel shows me the following message:
Cairo.Surface is leaking, programmer is missing a call to Dispose
Set MONO_CAIRO_DEBUG_DISPOSE to track allocation traces
The code that redraws a part of the widget is something like:
// SRGB is a custom struct, not from Gdk nor Cairo
void paintSingleBlock(SRGB color, int i)
{
using (Cairo.Context g = CairoHelper.Create (GdkWindow)) {
paintSingleBlock (g, color, i);
// We do this to avoid memory leaks. Cairo does not work well with the GC.
g.GetTarget().Dispose ();
g.Dispose ();
}
}
void paintSingleBlock(Cairo.Context g, SRGB color, int i)
{
var scale = Math.Pow (10.0, TimeScale);
g.Save();
g.Rectangle (x(i), y(i), w(i), h(i));
g.ClosePath ();
g.Restore ();
// We don't directly use stb.Color because in some cases we need more flexibility
g.SetSourceRGB (color.R, color.G, color.B);
g.LineWidth = 0;
g.Fill ();
}
The (second) problem: Ok, Monodevelop tells me that I should set MONO_CAIRO_DEBUG_DISPOSE to "track allocation traces" (In order to find the leak, I suppose)... but I don't know how to set this environment variable (I'm in Windows). I've tried using bash and executing something like:
MONO_CAIRO_DEBUG_DISPOSE=1 ./LightCreator.exe
But nothing appears in stderr nor stdout... (neither the messages that appear in the Monodevelop's applicationt trace panel). I also don't know how to get the debugging messages that see inside Monodevelop but without Monodevelop.
There's anyone with experience debugging GTK# or Cairo# memory leaks?
Thanks in advance.
Just wanted to throw my 2c here as I was fighting a similar leak problem in Cairo with surfaces. What I noticed is that if I create a Surface object the ReferenceCount property becomes 1 and if I attach this surface to a Context if becomes not 2 but 3. After disposing the Context the ReferenceCount comes back but to 2.
So I used some reflection to call the native methods in Cairo to decrease the ReferenceCount when I really want to Dispose a surface. I use this code:
public static void HardDisposeSurface (this Surface surface)
{
var handle = surface.Handle;
long refCount = surface.ReferenceCount;
surface.Dispose ();
refCount--;
if (refCount <= 0)
return;
var asm = typeof (Surface).Assembly;
var nativeMethods = asm.GetType ("Cairo.NativeMethods");
var surfaceDestroy = nativeMethods.GetMethod ("cairo_surface_destroy", BindingFlags.Static | BindingFlags.NonPublic);
for (long i = refCount; i > 0; i--)
surfaceDestroy.Invoke (null, new object [] { handle });
}
After using it I still have some leaks, but they seem to be related to other parts of Cairo and not with the surfaces.
I have found that a context created with CairoHelper.Create() will have a reference count of two.
A call to dispose reduces the reference count by one. Thus the context is never freed and keeps its target alive, too.
The native objects have manual reference counting, but the Gtk# wrappers want to keep a native object alive as long as there is a C# instance referencing it.
If a native object is created for a C# wrapper instance it does not need to increment the reference count because the wrapper instance 'owns' the native object and the reference count has the correct value of one. But if a wrapper instance is created for an already existing native object the reference count of the native object needs to be manually incremented to keep the object alive.
This is decided by a bool parameter when a wrapper instance is created.
Looking at the code for CairoHelper.Create() will show something like this
public static Cairo.Context Create(Gdk.Window window) {
IntPtr raw_ret = gdk_cairo_create(window == null ? IntPtr.Zero : window.Handle);
Cairo.Context ret = new Cairo.Context (raw_ret, false);
return ret;
}
Even though the native context was just created 'owned' will be false and the C# context will increment the reference count.
There is no fixed version right now, it can only be corrected by fixing the source and building Gtk# yourself.
CairoHelper is an auto-generated file, to change the parameter to true this attribute must be included in gdk/Gdk.metadata.
<attr path="/api/namespace/class[#cname='GdkCairo_']/method[#name='Create']/return-type" name="owned">true</attr>
Everything to build Gtk# can be found here.
https://github.com/mono/gtk-sharp

VC++ 2010 C2061 error

I am getting VC++ 2010 C2061 error on line:
#include "queryevaluator_p.h"
class QueryEvaluator {
public:
vector<AttrValue>* getCandidateList(QueryClause cl, int pos, ResultSet *computedRes);
...
Error 41 error C2061: syntax error : identifier 'ResultSet' h:\dropbox\sch\cs3202\code\source\includes\queryevaluator.h 40
ResultSet is a struct defined in "queryevaluator_p.h"
struct ResultSet{ //a set of result
bool valid;
vector<ResultRow> rows;
};
Whats wrong here? ResultSet can be used elsewhere
Maybe you have circular includes (queryevaluator_p.h includes the main header again) causing confusion. Depending on the exact setup this can lead to such an effect, because one of the files will have to be compiled first.
The solution would be to resolve the circular dependency by using a forward declaration instead of an include in one place. For example you could forward declare struct ResultSet instead of including the queryevaluator_p.h header.

Freeing a BSTR using ::SysFreeString(). More Platform Dependant?

I am writing a COM Server which have a plenty of Interfaces and methods. And most of the methods have the BSTR as the parameters and as local parameters used for the return. A snippet looks like
Update 5:
The real code. This fetches from bunch of Data based on a specific condition the DB to populate an array of Object.
STDMETHODIMP CApplication::GetAllAddressByName(BSTR bstrParamName, VARIANT *vAdddresses)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
//check the Database server connection
COleSafeArray saAddress;
HRESULT hr;
// Prepare the SQL Strings dan Query the DB
long lRecCount = table.GetRecordCount();
if (lRecCount > 0)
{
//create one dimension safe array for putting details
saAddress.CreateOneDim(VT_DISPATCH,lRecCount);
IAddress *pIAddress = NULL;
//retrieve details
for(long iRet = table.MoveFirst(),iCount=0; !iRet; iRet = table.MoveNext(),iCount++)
{
CComObject<CAddress> *pAddress;
hr = CComObject<CAddress>::CreateInstance(&pAddress);
if (SUCCEEDED(hr))
{
BSTR bstrStreet = ::SysAllocString(table.m_pRecordData->Street);
pAddress->put_StreetName(bstrStreet);
BSTR bstrCity = ::SysAllocString(table.m_pRecordData->City);
pAddress->put_CityName(bstrCity);
}
hr = pAddress->QueryInterface(IID_IAddress, (void**)&pIAddress);
if(SUCCEEDED(hr))
{
saAddress.PutElement(&iCount,pIAddress);
}
}
*vAdddresses=saAddress.Detach();
}
table.Close();
return S_OK;
}
STDMETHODIMP CAddress::put_CityName(BSTR bstrCityName)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
// m_sCityName is of CComBSTR Type
m_sCityName.Empty();//free the old string
m_sCityName = ::SysAllocString(bstrCityName);//create the memory for the new string
return S_OK;
}
The problem lies in the Memory Freeing part. The code works very fine in any Win XP machines, but when comes to WIN2K8 R2 and WIN7 the code crashes and pointing to the ::SysFreeString() as the culprit. The MSDN is not adequate to the solution.
Can anyone please help in finding the right solution?
Thanks a lot in advance :)
Update 1:
I have tried using the CComBSTR as per the suggestion in the place of raw BSTR, initialized using direct CString's and excluded the SysFreeString(). But for my trouble, on getting out of scope the system is calling the SysFreeString() which again causes the crash :(
Update 2:
With the same CComBSTR i tried to allocate using the SysAllocString() , the problem remains same :(
Update 3:
I am tired of all the options and in peace I am having only question in mind
Is it necessary to free the BSTR through SysFreeString() which was
allocated using SysAllocString()/string.AllocSysString()?
Update 4:
I missed to provide the information about the crash. When I tried to debug the COM server crashed with a error saying
"Possible Heap Corruption"
. Please help me out of here.. :(
// Now All Things are packed in to the Object
obj.Name = bstrName;
obj.Name2 = bstrname2;
I don't quite understand what do you mean by saying that things are packed since you're just copying pointers to the strings, and at the moment when you call SysFreeString obj.Name and obj.Name2 will point to an invalid block of memory. Although this code is not safe, it looks like if the source of your problem is class CFoo. You should show us more details of your code
I suggest you to use a CComBSTR class which will take a responsibility for releasing the memory.
UPDATE
#include <atlbase.h>
using namespace ATL;
...
{
CComBSTR bstrname(_T("Some Name"));
CComBSTR bstrname2(_T("Another Name"));
// Here one may work with these variables if needed
...
// Copy the local values to the Obj's member Variable
bstrname.Copy(&obj.Name);
bstrname2.Copy(&obj.Name2);
}
UPDATE2
First of all one should free bstrCity and bstrStreetName with SysFreeString or use CComBSTR instead within this block:
if (SUCCEEDED(hr))
{
BSTR bstrStreet = ::SysAllocString(table.m_pRecordData->Street);
pAddress->put_StreetName(bstrStreet);
BSTR bstrCity = ::SysAllocString(table.m_pRecordData->City);
pAddress->put_CityName(bstrCity);
// SysFreeString(bstrStreet)
// SysFreeString(bstrCity)
}
Consider to amplify the loop's condition !iRet with iCount < lRecCount.
for(...; !iRet /* && (iCount < lRecCount) */; ...)
Also, here:
m_sCityName = ::SysAllocString(bstrCityName);
you allocate memory but never release it since internally CComBSTR& operator = (OLESTR ..) allocates a new storage itself. One should rewrite is as follows:
m_sCityName = bstrCityName;
Everything else, looks good for me
UPDATE3
Well, Heap corruption is often a consequence of writing some values outside of the allocated memory block. Say you allocate an array of length 5 and put some value to the 6th position
Finally I have found the real reason for the Heap Corruption that happened in the code.
The put_StreetName/put_CityName of the IAddress/CAddress is designed in a following way.
STDMETHODIMP CAddress::put_CityName(BSTR bstrCityName)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
m_sCityName.Empty();
TrimBSTR(bstrCityName);
m_sCityName = ::SysAllocString(bstrCityName);
return S_OK;
}
BSTR CAddress::TrimBSTR(BSTR bstrString)
{
CString sTmpStr(bstrString);
sTmpStr.TrimLeft();
sTmpStr.TrimRight();
SysReAllocString(&bstrString,sTmpStr); // The Devilish Line
}
The Devilish Line of code is the real culprit that caused the Memory to go hell.
What caused the trouble?
In this line of code, the BSTR string passed as a parameter is from another application and the real memory is in another realm. So the system is trying to reallocate teh string. Either succeed or not, the same is tried to cleared off from the memory in original application/realm, thus causing a crash.
What still unsolved?
Why the same piece of code doesn't crashed a single time in Win XP and
older systems? :(
Thanks for all who took their time to answer and solve my problem :)

how to use window title to get process id,and process name

I would like to get process id and process name via using window title
my develop environment is visual c++ 2008
how to do it.
thanks
It's not reliable to search window by title. But if you want to do so, first you need to find window handle for specified title. You can easily do this with EnumWindows function. When you find HWND you can use GetWindowThreadProcessId function to get process id.
UPD: To get process name you need to get process handle with OpenProcess and use GetProcessImageFileName.
HWND hw = FindWindow(NULL, L"Window Title");
if (hw)
{
DWORD dwProcessId = 0;
DWORD dwThreadId = GetWindowThreadProcessId(hw, &dwProcessId);
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
if (hProcess)
{
wchar_t *szExeName[1024] = {0};
if (QueryFullProcessImageName(hProcess, 0, szExeName, _countof(szExeName))
{
// ...
}
CloseHandle(hProcess);
}
}
You should probably use the class argument as well (the one that is NULL in my first line) if you know it, so that it is less likely you will accidentally find some other program's window that happens to have the same title.
Of course, the class name is not guaranteed to be unique between programs either, but the combination is more reliable than just using the title by itself.
You can get the window class easily using Spy++.
Edit: QueryFullProcessImageName requires Vista, but you can swap that line for one which uses GetProcessImageFileName as per DReJ's answer.
Edit2: If you're not compiling for unicode, remove the "L" before "Window Title" and use a char buffer instead of wchar_t.

Resources