Where is the list of device driver images stored in ETW? - windows

I am trying to programatically get the list of device drives from an ETW with the great TraceProcessing Library which is used by WPA.
using ITraceProcessor processor = TraceProcessor.Create(myEtlFile, new
TraceProcessorSettings
{
AllowLostEvents = true,
AllowTimeInversion = true,
});
myProcesses = processor.UseProcesses();
foreach (var process in myProcesses.Result.Processes)
{
foreach (var dll in process.Images)
{
// get dll.Path, dll.FileVersion, dll.ProductVersion, dll.ProductName, dll.FileVersionNumber, dll.FileDescription
}
}
This works for every process except the Kernel (System(4)). Why do I have only 3 dlls in the System process? I would expect the driver files in the System process there as well. In CPU sampling the image is there so it looks like everything is right there.
This would be very useful to check for driver versions if the data is present. But so far I was not able to find it. Am I missing something here?

Happy to hear you enjoy using the TraceProcessor library!
Device drivers are logged against the "Idle (0)" process by ETW, here is an example:
using var tp = TraceProcessor.Create(#"trace.etl");
var processes = tp.UseProcesses();
tp.Process();
var idleProcess = processes.Result.Processes.FirstOrDefault(x => x.Id == 0);
foreach (var image in idleProcess?.Images)
{
Console.WriteLine(image.Path);
}

Related

Load JSON From External Storage

I am building an app for an LG Smart TV. I need to load json data from a USB drive when it's inserted into the smart TV.
I'm not sure how to do this, never worked on an app like this.
My question is how do I gain access to external storage and load json data into my app?
Using the SCAP API (v1.2+)
function readFile() {
var successCb = function (cbObject) {
var data_text = cbObject.data;
// do something with the json string
};
var failureCb = function (cbObject) {
var errorCode = cbObject.errorCode;
var errorText = cbObject.errorText;
// do something with the error
};
// Read the whole file from the beginning, as a text file.
var options = {
path: "file://usb:[INDEX]/[FILE_PATH]",
position: 0,
encoding: 'utf8'
};
var storage = new Storage();
storage.readFile(successCb, failureCb, options);
}
The filepath for a usb is file://usb:[INDEX]/[FILE_PATH] [INDEX] is the usb index (could have multiple USBs connected).
Additional help can be found here: http://webossignage.developer.lge.com/api/scap-api/scap16/storage/?wos_flag=readFile#readFile
You can use getStorageInfo() to check if your usb is available.

Determine GPU manufacturer on Windows

I'm going to write a Windows application and it would be useful if the app could tell what graphics card is being used. At the least, it would be helpful to see the manufacturer of the GPU. I'm not set on a programming language as of yet.
What windows library exposes this information?
See here for a C# way of doing it, using WMI. You could access WMI through pretty much any language:
C# detect which graphics card drives video
ManagementObjectSearcher searcher
= new ManagementObjectSearcher("SELECT * FROM Win32_DisplayConfiguration");
string graphicsCard = string.Empty;
foreach (ManagementObject mo in searcher.Get())
{
foreach (PropertyData property in mo.Properties)
{
if (property.Name == "Description")
{
graphicsCard = property.Value.ToString();
}
}
}

Caching an aggregate of data with Service stack ToOptimizedResultUsingCache

I am currently using Service stack ICacheClient to cache in memory.
Note: the code below is some what pseudo code as I needed to remove customer specific names.
Lets say I have the following aggregate:
BlogPost
=> Comments
I want to do this following:
// So I need to go get the blogPost and cache it:
var blogPostExpiration = new TimeSpan(0, 0, 30);
var blogPostCacheKey = GenerateUniqueCacheKey<BlogPostRequest>(request);
blogPostResponse = base.RequestContext.ToOptimizedResultUsingCache<BlogPostResponse>(base.CacheClient, blogPostCacheKey, blogPostExpiration, () =>
_client.Execute((request)));
// Then, annoyingly I need to decompress it to json to get the response back into my domain entity structure: BlogPostResponse
string blogJson = StreamExtensions.Decompress(((CompressedResult)blogPostResponse).Contents, CompressionTypes.Default);
response = ServiceStack.Text.StringExtensions.FromJson<BlogPostResponse>(blogJson);
// Then I do the same so get the comments:
var commentsExpiration = new TimeSpan(0, 0, 30);
var commentsCacheKey = GenerateUniqueCacheKey<CommentsRequest>(request);
var commentsResponse = base.RequestContext.ToOptimizedResultUsingCache<CommentsResponse>(base.CacheClient, commentsCacheKey, commentsExpiration, () =>
_client.Execute((request)));
// And decompress again as above
string commentsJson = StreamExtensions.Decompress(((CompressedResult)commentsResponse).Contents, CompressionTypes.Default);
var commentsResponse = ServiceStack.Text.StringExtensions.FromJson<CommentsResponse>(commentsJson);
// The reason for the decompression becomes clear here as I need to attach my Comments only my domain emtity.
if (commentsResponse != null && commentsResponse.Comments != null)
{
response.Comments = commentsResponse.Comments;
}
What I want to know is there a shorter way to do the follow:
Get my data and cache it, get it back into my domain entity format without having to write all the above lines of code. I dont want to go through the following pain!:
Domain entity => json => decompress => domain entity.
Seems like a lot of wasted energy.
Any sample code or pointers to a better explanation of ToOptimizedResultUsingCache would be much appreciated.
Ok so im going to answer my own question. It seems that methods (extension methods) like ToOptimizedResult and ToOptimizedResultUsingCache are there to give you stuff like compression and caching for free.
But, if you want more control you just use the cache as you would normally:
// Generate cache key
var applesCacheKey = GenerateUniqueCacheKey<ApplesRequest>(request);
// attempt to get match details from cache
applesResponse = CacheClient.Get<ApplesDetailResponse>(applesDetailCacheKey);
// if there was nothing in cache then
if (applesResponse == null)
{
// Get data from storage
applesResponse = _client.Execute(request);
// Add the data to cache
CacheClient.Add(applesCacheKey, applesResponse, applesExpiration);
}
After you build up you aggregate and put it into cache you can compress the whole thing:
return base.RequestContext.ToOptimizedResult(applesResponse);
If you want to compress globally you can follow this post:
Enable gzip/deflate compression
Hope this makes sense.
RuSs

C# WIA with Automatic Document Feeder (ADF) retuns only one page on certain scanners

I have a HP Scanjet 7000 (duplex & ADF scanner) and a HP Scanjet 5500c (only ADF) and a scanner program I'm developing which uses WIA 2.0 on Windows 7.
The problem is that the code works perfectly on the older scanner model, but on the newer one the code seems to run just fine through the first page, then fail on the second. If I step through the code around the following line;
image = (WIA.ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatTIFF, false);
the old scanner stops and waits for another call to be made on the same reference, but the newer one just runs through all it's pages from the feeder in one continuous operation.
I notice if I'm using the default scanning program in Windows 7, the newer one returns a single .tif file which contains all the separate pages. The older one returns separate .jpg files (one for each page).
This indicates to me that the newer scanner is scanning through its whole feeder before it is ready to return a collection of images where the older one returns ONE image between each page scanned.
How can I support this behavior in code? The following is part of the relevant code which works on the older scanner model:
public static List<Image> Scan(string scannerId)
{
List<Image> images = new List<Image>();
List<String> tmp_imageList = new List<String>();
bool hasMorePages = true;
bool useAdf = true;
bool duplex = false;
int pages = 0;
string fileName = null;
string fileName_duplex = null;
WIA.DeviceManager manager = null;
WIA.Device device = null;
WIA.DeviceInfo device_infoHolder = null;
WIA.Item item = null;
WIA.ICommonDialog wiaCommonDialog = null;
manager = new WIA.DeviceManager();
// select the correct scanner using the provided scannerId parameter
foreach (WIA.DeviceInfo info in manager.DeviceInfos)
{
if (info.DeviceID == scannerId)
{
// Find scanner to connect to
device_infoHolder = info;
break;
}
}
while (hasMorePages)
{
wiaCommonDialog = new WIA.CommonDialog();
// Connect to scanner
device = device_infoHolder.Connect();
if (device.Items[1] != null)
{
item = device.Items[1] as WIA.Item;
try
{
if ((useAdf) || (duplex))
SetupADF(device, duplex); //Sets the right properties in WIA
WIA.ImageFile image = null;
WIA.ImageFile image_duplex = null;
// scan image
image = (WIA.ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatTIFF, false);
if (duplex)
{
image_duplex = (ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatPNG, false);
}
// save (front) image to temp file
fileName = Path.GetTempFileName();
tmp_imageList.Add(fileName);
File.Delete(fileName);
image.SaveFile(fileName);
image = null;
// add file to images list
images.Add(Image.FromFile(fileName));
if (duplex)
{
fileName_duplex = Path.GetTempFileName();
tmp_imageList.Add(fileName_duplex);
File.Delete(fileName_duplex);
image_duplex.SaveFile(fileName_duplex);
image_duplex = null;
// add file_duplex to images list
images.Add(Image.FromFile(fileName_duplex));
}
if (useAdf || duplex)
{
hasMorePages = HasMorePages(device); //Returns true if the feeder has more pages
pages++;
}
}
catch (Exception exc)
{
throw exc;
}
finally
{
wiaCommonDialog = null;
manager = null;
item = null;
device = null;
}
}
}
device = null;
return images;
}
Any help on this issue would be very much appreciated! I can't seem to find a working solution on the web. Just unanswered forum posts from people with the same problem.
we had a very similar problem and various solutions, e.g. by setting certain properties, did not help. The main problem was that the scanner (ADF) retracted all pages on startup, regardless of what was happening in the program code.
The process repeatedly led to errors, since "too much" was made before the next page was scanned. This applies in particular to the fact that another "Connect" was attempted.
For this reason, we have modified the code so that the individual pages can be read in as quickly as possible:
public List<Image> Scan(string deviceID)
{
List<Image> images = new List<Image>();
WIA.ICommonDialog wiaCommonDialog = new WIA.CommonDialog();
WIA.Device device = this.Connect(deviceID);
if (device == null)
return images;
WIA.Item item = device.Items[1] as WIA.Item;
List<WIA.ImageFile> wiaImages = new List<ImageFile>();
try
{
// scan images
do
{
WIA.ImageFile image = (WIA.ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatJPEG, false);
wiaImages.Add(image);
} while (true);
}
catch (System.Runtime.InteropServices.COMException ex)
{
if ((uint)ex.ErrorCode != WIA_PROPERTIES.WIA_ERROR_PAPER_EMPTY)
throw ex;
}
catch (Exception ex)
{
throw ex;
}
foreach (WIA.ImageFile image in wiaImages)
this.DoImage(images, image);
return images;
}
I see you're calling a method called SetupADF, which is not shown, that presumably sets some properties on the device object. Have you tried setting WIA_DPS_PAGES (property 3096) and/or WIA_DPS_SCAN_AHEAD_PAGES (property 3094)?
I have a blog post about scanning from an ADF in Silverlight, and I believe a commenter came up against the same issue you're having. Setting WIA_DPS_PAGES to 1 fixed it for him. I ended up modifying my code's SetDeviceProperties method to set WIA_DPS_PAGES to 1 and WIA_DPS_SCAN_AHEAD_PAGES to 0.
After alot of trial and error I stumbled upon a solution which worked for reasons I'm not quite sure of. It seems like the ShowTransfer() method was unable to convert the page to .png or .tiff WHILE scanning. Setting the format to JPEG or BMP actually solved the issue for me:
image = (ImageFile)scanDialog.ShowTransfer(item, wiaFormatJPEG, false);
I think I saw somewhere on the web that this method actually returns BMP regardless of the format specified. Might be that converting the image to png or tiff is too heavy as opposed to using bmp or jpeg.
On a sidenote, I'm setting the property setting: 3088 to 0x005 (adf AND duplex mode).

Windows Workflow Foundation 4.0 and Tracking

I'm working with the Beta 2 version of Visual Studio 2010 to get some advanced learning using WF4. I've been working with the SqlTracking Sample in the WF_WCF_Samples SDK, and have gotten a pretty good understanding of how to emit and store tracking data in a SQL Database, but haven't seen anything on how to query the data when needed. Does anyone know if there are any .Net classes that are to be used for querying the tracking data, and if so are there any known samples, tutorials, or articles that describe how to query the tracking data?
According to Matt Winkler, from the Microsoft WF4 Team, there isn't any built in API for querying the tracking data, the developer must write his/her own.
These can help:
WorkflowInstanceQuery Class
Workflow Tracking and Tracing
Tracking Participants in .NET 4 Beta 1
Old question, I know, but there is actually a more or less official API in AppFabric: Windows Server AppFabric Class Library
You'll have to find the actual DLL's in %SystemRoot%\AppFabric (after installing AppFabric, of course). Pretty weird place to put it.
The key classes to look are at are SqlInstanceQueryProvider, InstanceQueryExecuteArgs. The query API is asynchronous and can be used something like this (C#):
public InstanceInfo GetWorkflowInstanceInformation(Guid workflowInstanceId, string connectionString)
{
var instanceQueryProvider = new SqlInstanceQueryProvider();
// Connection string to the instance store needs to be set like this:
var parameters = new NameValueCollection()
{
{"connectionString", connectionString}
};
instanceQueryProvider.Initialize("Provider", parameters);
var queryArgs = new InstanceQueryExecuteArgs()
{
InstanceId = new List<Guid>() { workflowInstanceId }
};
// Total ruin the asynchronous advantages and use a Mutex to lock on.
var waitEvent = new ManualResetEvent(false);
IEnumerable<InstanceInfo> retrievedInstanceInfos = null;
var query = instanceQueryProvider.CreateInstanceQuery();
query.BeginExecuteQuery(
queryArgs,
TimeSpan.FromSeconds(10),
ar =>
{
lock (synchronizer)
{
retrievedInstanceInfos = query.EndExecuteQuery(ar).ToList();
}
waitEvent.Set();
},
null);
var waitResult = waitEvent.WaitOne(5000);
if (waitResult)
{
List<InstanceInfo> instances = null;
lock (synchronizer)
{
if (retrievedInstanceInfos != null)
{
instances = retrievedInstanceInfos.ToList();
}
}
if (instances != null)
{
if (instances.Count() == 1)
{
return instances.Single();
}
if (!instances.Any())
{
Log.Warning("Request for non-existing WorkflowInstanceInfo: {0}.", workflowInstanceId);
return null;
}
Log.Error("More than one(!) WorkflowInstanceInfo for id: {0}.", workflowInstanceId);
}
}
Log.Error("Time out retrieving information for id: {0}.", workflowInstanceId);
return null;
}
And just to clarify - this does NOT give you access to the tracking data, which are stored in the Monitoring Database. This API is only for the Persistence Database.

Resources