How to convert UnicodeString to BSTR? - c++

I'm having a problem when calling OpenDatabase function (DAO). It's prototipe is:
virtual HRESULT STDMETHODCALLTYPE OpenDatabase(BSTR Name/*[in]*/, VARIANT Options/*[in,opt]*/,
VARIANT ReadOnly/*[in,opt]*/,
VARIANT Connect/*[in,opt]*/,
Dao_tlb::Database** ppDb/*[out,retval]*/) = 0; // [-1]
So, when I do this:
if(OpenDialog1->Execute() != true) return;
The selected filename is saved in OpenDialog1->FileName. Then I call the function above:
pDatabasePtr = pDBEngine->OpenDatabase(WideString(OpenDialog1->FileName).c_bstr(), myOpts, myRead, myCon);
and this works! But, the problem is when I try to set the filename to something else:
OpenDialog1->FileName = ParamStr(1); // OpenDatabase don't work in runtime - file not recognised!
or even set the filename inside a function:
pDatabasePtr = pDBEngine->OpenDatabase(WideString(L"SomeDB.mdb").c_bstr(), myOpts, myRead, myCon);
In both cases I get strange errors and never able to open a database. So, I probably convert UnicodeString/WideString to BSTR incorrectly.
So, why this function (OpenDatabase) works with
if(OpenDialog1->Execute() != true) return;
and does not work with
OpenDialog1->FileName = ParamStr(1);
How do I set the conversion correctly?

I found answer in here if anyone else needs it:
https://forums.embarcadero.com/thread.jspa?messageID=498776

Related

TaskDialogIndirect is returning an unusual error code

I'm using TaskDialogIndirect to display prompts to the user. Normally this works just fine, but sometimes, after the program has been running for a while, it begins returning an error code that the MSDN entry does not list as being one of the error codes this function can return.
0x80040001 OLE_E_ADVF "Invalid advise flags"
I have checked all the inputs to the function against previous successful calls in the same run. Aside from differences in the string to be displayed, they are identical. (the strings are even the same length.)
// create task dialog struct
TASKDIALOGCONFIG tdc;
ZeroMemory(&tdc, sizeof(TASKDIALOGCONFIG));
tdc.cbSize = sizeof(tdc);
tdc.dwFlags = (((dwMessageBoxFlags & MB_OKCANCEL) == MB_OKCANCEL) ? TDF_ALLOW_DIALOG_CANCELLATION : 0) | TDF_POSITION_RELATIVE_TO_WINDOW;
tdc.hwndParent = hwndOwner;
tdc.hInstance = LGetHInstance();
tdc.pszContent = usrText.wsz;
tdc.pButtons = _pButtons;
tdc.cButtons = nButtons;
tdc.pszMainIcon = pszTaskDialogIcon;
tdc.pszWindowTitle = usrCaption.wsz;
tdc.nDefaultButton = nDefaultButton;
// display it now
int iButton = 0;
BOOL b = 0;
HRESULT hResult = TaskDialogIndirect(&tdc, &iButton, NULL, &b);
NEW INFORMATION
At the same time that TaskDialogIndirect stops behaving correctly, ShellExecute also stops working, as does CreateFile.
This was actually caused by an event handle leak elsewhere. When the available handles ran out, no more API calls which needed to create a handle could succeed. They did return a rather odd set of error codes though, none of which was "out of handles".

ADO Recordset->EndOfFile giving me _com_error when Empty Recordset

I'm using ADO, and getting a very weird com error.
So I'm simply running a stored proc using ADO CommandPtr, and storing it in a Recordset.
Here is what I'm doing:
_ConnectionPtr Connptr;
//Instantiate ConnectionPtr...
_CommapndPtr CommPtr;
CommPtr.CreateInstance(__uuidof(Command));
CommPtr->CommandType = adCmdText;
CommPtr->ActiveConnection = ConnPtr;
CommPtr->CommandText = "Execute MyDb..MyStoredProc";
_RecordsetPtr RecPtr;
RecPtr.CreateInstance(__uuidof(Recordset));
RecPtr->CursorLocation = adUseClient;
RecPtr->CacheSize = 150;
RecPtr = CommPtr->Execute(NULL, NULL, adOptionUnspecified); //RecPtr = Empty Recordset
while (!RecPtr->EndOfFile) { //ERROR HAPPENS HERE!!!
//Do something
RecPtr->MoveNext();
}
So my stored procedure is supposed to returns an empty recordset (0 rows).
But then , when I check if the recordset has reached the end (which should simply return true if it is empty). I get a com error.
When I caught the com error and printed it out, I got this.
Code = -2147217849
Meaning = IDispatch error #3153
Source = NULL
Which doesn't tell me much.
I don't understand why RecPtr->EndofFile is throwing a com error, since it should simply return true/false.
I highly doubt that the error is caused because I'm doing something wrong when initializing Connection and Command objects. (If so, then I would have gotten the error when Executing the command.)
Any ideas on what might be causing this exception?

How to display absolute path with device name of currently opened file

The first two lines of this code showing file name excluding device name like /Document/temp but I want
to show also device name like L"\Device\Harddisk0\DR0\Document\temp. I am using this code to call ObQueryNameString routine but it is showing NULL.
Please tell me what is wrong with code. I think memory is not allocating
properly.
PFILE_OBJECT pFileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
if (pFileObject)
{
DbgPrint("FileName : %wZ\n", pFileObject->FileName);
}
NTSTATUS status = STATUS_UNSUCCESSFUL;
OBJECT_NAME_INFORMATION objName = {0};
ULONG ReturnLength = 1024;
ObQueryNameString(DeviceObject, objName, sizeof(objName), ReturnLength);
DbgPrint("FileName : %wZ\n", &objName);
Have you considered using GetFullPathName function?
Refer to http://msdn.microsoft.com/en-us/library/aa364963%28VS.85%29.aspx for more accurate explanation what it does.

Using UpdateResource with StringTables in C++

I need to edit the resources of a file in C++ using UpdateResource(), however I am unsure on how to go about getting the data for the 5th parameter (lpData).
I have no idea about how to create the data that needs to be provided for the function and the structure of the data, Can anybody provide guidance on how to go about getting/creating the data?
Simply you can use:
wchar_t wszMyText[] = L"Some text";
HANDLE hUpdate = BeginUpdateResourceW( L"/path/to/file", FALSE );
// test return value.
BOOL res = UpdateResourceW( hUpdate, RT_STRING, L"MyResource", wszMyText,
sizeof(wszMyText) - sizeof(wchar_t);
// check return value
EndUpdateResource( hUpdate, FALSE );

Unable to set Reporting Services Parameters

I'm generating a reporting services report from an ASP.NET (MVC) based application but am having problems setting the parameters for the report.
I believe the issue has only occurred since we upgraded SQL Server from 2005 to 2008 R2 (and Reporting Services along with it).
The original error encountered was from calling rsExec.Render:
Procedure or function 'pCommunication_ReturnRegistrationLetterDetails'
expects parameter '#guid', which was not supplied.
Debugging the code I noticed that rsExec.SetExecutionParameters is returning the following response:
Cannot call 'NameOfApp.SQLRSExec.ReportExecutionService.SetExecutionParameters(NameOfApp.SQLRSExec.ParameterValue[],
string)' because it is a web method.
Here is the function in it's entirety:
public static bool ProduceReportToFile(string reportname, string filename, string[,] reportparams,
string fileformat)
{
bool successful = false;
SQLRS.ReportingService2005 rs = new SQLRS.ReportingService2005();
SQLRSExec.ReportExecutionService rsExec = new NameOfApp.SQLRSExec.ReportExecutionService();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
rsExec.Credentials = System.Net.CredentialCache.DefaultCredentials;
// Prepare Render arguments
string historyID = null;
string deviceInfo = null;
// Prepare format - available options are "PDF","Word","CSV","TIFF","XML","EXCEL"
string format = fileformat;
Byte[] results;
string encoding = String.Empty;
string mimeType = String.Empty;
string extension = String.Empty;
SQLRSExec.Warning[] warnings = null;
string[] streamIDs = null;
// Define variables needed for GetParameters() method
// Get the report name
string _reportName = reportname;
string _historyID = null;
bool _forRendering = false;
SQLRS.ParameterValue[] _values = null;
SQLRS.DataSourceCredentials[] _credentials = null;
SQLRS.ReportParameter[] _parameters = null;
// Get if any parameters needed.
_parameters = rs.GetReportParameters(_reportName, _historyID,
_forRendering, _values, _credentials);
// Load the selected report.
SQLRSExec.ExecutionInfo ei =
rsExec.LoadReport(_reportName, historyID);
// Prepare report parameter.
// Set the parameters for the report needed.
SQLRSExec.ParameterValue[] parameters =
new SQLRSExec.ParameterValue[1];
// Place to include the parameter.
if (_parameters.Length > 0)
{
for (int i = 0; i < _parameters.Length; i++)
{
parameters[i] = new SQLRSExec.ParameterValue();
parameters[i].Label = reportparams[i,0];
parameters[i].Name = reportparams[i, 0];
parameters[i].Value = reportparams[i, 1];
}
}
rsExec.SetExecutionParameters(parameters, "en-us");
results = rsExec.Render(format, deviceInfo,
out extension, out encoding,
out mimeType, out warnings, out streamIDs);
// Create a file stream and write the report to it
using (FileStream stream = System.IO.File.OpenWrite(filename))
{
stream.Write(results, 0, results.Length);
}
successful = true;
return successful;
}
Any ideas why I'm now unable to set parameters? The report generation works without issue if parameters aren't required.
Looks like it may have been an issue with how reporting services passes parameters through to the stored procedure providing the data. A string guid was being passed through to the report and the stored procedure expected a varchar guid. I suspect reporting services may have been noticing the string followed the guid format pattern and so passed it through as a uniqueidentifier to the stored procedure.
I changed the data source for the report from "stored procedure" to "text" and set the SQL as "EXEC pMyStoredOProcName #guid".
Please note the guid being passed in as a string to the stored procedure is probably not best practice... I was simply debugging an issue with another developers code.
Parameter _reportName cannot be null or empty. The [CLASSNAME].[METHODNAME]() reflection API could not create and return the SrsReportNameAttribute object
In this specific case it looks like an earlier full compile did not finish.
If you encounter this problem I would suggest that you first compile the class mentioned in the error message and see if this solves the problem.
go to AOT (get Ctrl+D)
in classes find CLASSNAME
3.compile it (F7)