First let me tell you I'm new to the .NET world, but have been Software Emgineer for 16 years, so I'm not new to coding. I ran across something that has me baffled, and maybe a more seasoned .NET developer might know what is causing a perfomance issue of my COM object. I have spent days browsing through forums with no luck, I decide to seek help by putting this post together. I have developed my .NET code in VS 2010 using C#. I know, the IDE is little aged. The code is pretty simple. The main method takes the Certificates encoded string, converts it to a byte format, and passes that to the X509Certificate object. I then use the objects method to get the expiration date. I also added a memory clean-up class hoping it would solve my problem. It did not.
using System;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Runtime.InteropServices; //Need for API
namespace CertificationInfo
{
//Certification Class
public class CertificateInformation
{
//[DllImport("kernel32.dll")]
//public static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max);
//Class Attributes
//private X509Certificate CertificateObject;
public string CertificateData;
public string ExpirationDate;
private MemoryManagement MemMngr;
//Constructor
public CertificateInformation()
{
//Reset Expiration Date
this.ExpirationDate = "";
MemMngr = new MemoryManagement();
}
//Method
public string GetCertExpirationDate(string rawdata)
{
try
{
//Clean Up Memory
this.MemMngr.ReleaseMemory();
//Reset Expiration Date Property
this.ExpirationDate = "";
//Check for data
if (rawdata == "" && this.CertificateData == "")
{
//Nothing is passed & property is blank
this.ExpirationDate = "";
}
else
{
//Check for Raw Data value
if (rawdata != "")
{
this.CertificateData = rawdata;
}
//Convert Property Array
//Might be best to use unicode Under Encoding namespace
//System.Text.UnicodeEncoding Encoding0=new System.Text.UnicodeEncoding();
//Byte[] bytedata0=Encoding0.GetBytes(rawdata);
//Convert Property to byte array
System.Text.ASCIIEncoding Encoding = new System.Text.ASCIIEncoding();
Byte[] bytedata = Encoding.GetBytes(this.CertificateData);
//Create Encoding Object
X509Certificate CertificateObject = new X509Certificate(bytedata);
//this.CertificateObject = new X509Certificate(bytedata);
//Might have to check to see iff cert object is null though catch should pick it up
//Get Expiration date
this.ExpirationDate = CertificateObject.GetExpirationDateString();
//Reset Object & Certificate Data Property
CertificateObject = null;
Encoding = null;
this.CertificateData = "";
//Clean Up Memory
this.MemMngr.ReleaseMemory();
}
}
//Error Trapping in case of error still returns something
catch
{
this.ExpirationDate = "";
}
return this.ExpirationDate;
}
}
//API Class to Clean up Memory threads
public class MemoryManagement
{
//Memory Management API
[DllImport("kernel32.dll")]
public static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max);
//Method
public void ReleaseMemory()
{
GC.Collect();
GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
}
}
}
}
I moved it into the GAC, and registered it as a DLL on my local machine. I then created a Lotus Script agent, that loops through all my documents(records). In the iteration it pulls a field into a string, passes it to method, and returns the expiration date as a string
%REM
Agent TestDLL
Created Jan 13, 2014 by Keith Wiwel/TPS/PGH/PNC
Description: Comments for Agent
%END REM
Option Public
Option Declare
Sub Initialize
Dim Session As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Dim document As NotesDocument
Dim COMObj As Variant
'Counts
Dim TotalCount As Long
Dim MissingDataCount As Long
Dim COMErrorCount As Long
Dim COMSuccessCount As Long
Print "ETH - GetExpirationDLL: Initializing Notes Objects"
Set db=Session.Currentdatabase
Set view=db.Getview("Active Certificates - By Web Site")
Print "ETH - GetExpirationDLL: Initializing COM Object"
Set COMObj=CreateObject("CertificationInfo.CertificateInformation")
TotalCount=0
MissingDataCount=0
COMErrorCount=0
COMSuccessCount=0
Print "ETH - GetExpirationDLL: Start Processing"
Set document=view.Getfirstdocument()
Do Until document Is Nothing
TotalCount=TotalCount+1
Print "Processing..."+CStr(TotalCount)
'Expiration Variables
Dim expirationdate As String
Dim rawdata As String
Dim legacyexpirationdate As String
'Get data & Legacy Values
'rawdata
rawdata=CStr(Trim(document.Getitemvalue("CRT_File")(0)))
legacyexpirationdate=CStr(document.expirationdate(0))
If rawdata="" Then
'Capture Certificates with No CSR Data
document.ExpirationDate=""
If LegacyExpirationDate="" Then
document.LegacyExpirationDate=legacyexpirationdate
End If
document.COMError="Missing CSR"
Call document.Save(True,False)
MissingDataCount=MissingDataCount+1
Else
'Capture Legacy & Certificate Expiration Date
If legacyexpirationdate="" Then
document.LegacyExpirationDate=legacyexpirationdate
End If
Dim Certificatedat As String
CertificateDat=ComObj.CertificateData
'expirationdate=ComObj.ExpirationDate
expirationdate=COMObj.GetCertExpirationDate(rawdata)
Dim CertDate As String
CertDate=ComObj.ExpirationDate
Dim Debug As String
Debug=ComObj.xx
Print "Com expiration:" +CStr(ComObj.ExpirationDate)
If CStr(expirationdate)<>"" Then
'Success - Processing Expiration date
document.ExpirationDate=CStr(expirationdate)
COMSuccessCount=COMSuccessCount+1
Else
'Failed - Processing Expiration date
document.ExpirationDate=CStr(expirationdate)
document.COMError="COM Expiration Failed"
COMErrorCount=COMErrorCount+1
End If
Call document.Save(True,False)
End If
Set document=view.getnextdocument(document)
Loop
'Log Report
Print "ETH - GetExpirationDLL: Processed "+CStr(TotalCount)+" certificates."
Print "ETH - GetExpirationDLL: "+CStr(MissingDataCount)+" certificates had missing CSR data."
Print "ETH - GetExpirationDLL: "+CStr(COMErrorCount)+" certificates failed in the COM Object."
Print "ETH - GetExpirationDLL: "+CStr(COMSuccessCount)+" certificates were succesfully processed."
Print "ETH - GetExpirationDLL: End Processing"
'Delete COMObj
End Sub
The two main lines of code above are:
Set COMObj=CreateObject("CertificationInfo.CertificateInformation")
which creates the COM object. The other is:
expirationdate=expirationdate=COMObj.GetCertExpirationDate(rawdata)
which uses the method to pull the expiration date. As you might have expected, it works fine, however this is where my problem occurs. When I first ran the code it flew, it took roughly 10 minutes to go through 4,000+ records. I had a few anomalies that I wanted to check, so I ran it a couple more times. Each time it degraded, and enventually started crawling. My first thought was it was a memory leak. Since I was running it locally, I decided to turn off the power to the pc see if it cleared. It did not. I also installed it on my laptop to prove to myself it ran smotthly on it's first run. Ran fine on the first one, then perfomance started degrading on consecutive runs. Last day it was running so slow it was over 8+ hours. This is local machine testing so there are is no servers to contend with network traffic. I am at a complete loss, can anyone tell me what is going on? CPU is at 20% when running, and Mem usage for notes2.exe growsa little each time. It slows down when it enters:
expirationdate=expirationdate=COMObj.GetCertExpirationDate(rawdata)
That's the bottleneck. I am completely stuck, does anyone know what is going on?
Related
I am trying to simulate navigating Netgear Managed Switch (GC108PP) local UI webpage in C#. When sending HttpWebRequest using a Chrome browser, I've learned using Fiddler - there are 3 WebForms that are generated when hitting this URL:
http://192.168.50.101
ends up being:
http://192.168.50.101/cgi/get.cgi?cmd=home_login&dummy=1582137153063&bj4=3f104a21e12a9584d36372142f16e35b
WebForms:
cmd=home_login
dummy=1582137153063 (time since epoch, this one was easy to figure out)
bj4=3f104a21e12a9584d36372142f16e35b (trying to figure out how to generate this one)
There is no HTTP API to reference from Netgear. I have tried just generating a 32 char string with:
private static Random random = new Random();
public static string randomString(int length)
{
const string chars = "abcdef0123456789";
return new string(Enumerable.Repeat(chars, length).Select(s =>s[random.Next(s.Length)]).ToArray());
}
However, I get ERROR 400 Bad Request.If I use a bj4 key/ID that gets generated by my browser statically in my code it works, but I want to be generating this webform properly.
Any ideas on how this WebForm might be be generated?
Found it in the JS...
function gotoLogin()
{
document.cookie = \"testcookie\";
cookieEnabled = (document.cookie.indexOf(\"testcookie\") != -1) ? true : false;
if (cookieEnabled == false)
{
alert(\"Browser does not accept cookies. Please configure your browser to accept cookies in order to access the Web Interface.\");
}
var fileVer = (new Date().getTime());
var url = \"login.html?aj4=\"+fileVer;
url = url + '&bj4=' + md5(url.split('?')[1]); //here!!!
window.location.href=url;
}
In addin for Sparx EA I use this code to get pictures and assign to entity. Then I use images from entities, to, as example, save at some folders or insert in word report etc (from this answer)
/// <summary>
/// Access to diagram image without using clipboard
/// </summary>
/// <param name="projectInterface">Ea Sparx interface</param>
/// <param name="eaDiagramGuid">Guid of the diagramm</param>
/// <returns></returns>
public static Image GetDiagramImage(this Project projectInterface, Guid eaDiagramGuid, ApplicationLogger _logger)
{
Image diagramImage;
try
{
var diagramByGuid = projectInterface.GUIDtoXML(eaDiagramGuid.ToString("B"));
string tempFilename = string.Format("{0}{1}{2}", Path.GetTempPath(), Guid.NewGuid().ToString(), ".png");
bool imageToFileSuccess = projectInterface.PutDiagramImageToFile(diagramByGuid, tempFilename, FileExtensionByName);
if (imageToFileSuccess)
{
using (var imageStream = new MemoryStream(File.ReadAllBytes(tempFilename)))
{
diagramImage = Image.FromStream(imageStream);
}
File.Delete(tempFilename);
}
else
{
throw new Exception(string.Format("Image to file exprot fail {0}", projectInterface.GetLastError()));
}
}
catch (Exception e)
{
throw;
}
return diagramImage;
}
The problem is - it works if project I work with saved as .eap file.
If it's .feap file, which, as I believe means that it works with Firebird database (instead of Access), all saved/exproted to report images are blank, like this down below
Why does it happens and is there workaround?
UPD
It works if I use projectInterface.PutDiagramImageOnClipboard instead but I don't wont to use clipboard at all
UPD 2
After some experiments today at the morning (at my timezone, gmt+3, it's still morning) I found out that the problem was with GUIDs register!
After I decided to apply .toUpper() here
var diagramByGuid = projectInterface.GUIDtoXML(eaDiagramGuid.ToString("B").ToUpper());
it started work fine!
Strange thing thou that if project is *.EAP type everything works even when guid is not in upper register!
UPD3
Well, unfortunately, I was wrong. Some pictures are still blank. But somehow that changes got impact on diagrams, I keep testing this stuff.
And some of the pictures are appeared twice or in wrong place.
But it's kinda interesting (if I could say so) behaviour.
UPD 4
I was wrong in my UPD2 part! GUID can contain down register symbols as well as upper ones.
So, first I removed that part.
What I done next - I started to pass GUID directly from diagram, so signature changed like that
public static Image GetDiagramImage(this Project projectInterface, string eaDiagramGuid, ApplicationLogger _logger)
and eaDiagramGuid should be passed right from EA.Diagram object.
When we parse it as Guid by Guid.Parse(eaDiagramGuid) it convert everything in lowercase like here
so, thats why I got the problem.
But for some reason it was not appeared in *.EAP type of projects!
Also it strange that register matters in that case, really. Seems like GUID in common and GUID in sparx ea are different things!
Okay, as I founded out here, the thing is, in case of *.FEAP all items GUIDs are surprisingly case sensetive.
So, my mistake was to store item GUID as Guid type - when we use Guid.Parse(myGuidString) function and then we converting it back to string - all symbols are appers to be in lowercase.
Also, I got my answer from support (they were surprisingly fast, I really like that)
Hello Danil,
Running over the Stack Overflow - it sounds like it's effectively
answered. The core point is that the Feap files are case sensitive.
To be technical, the collation used for our Firebird databases is case
sensitive.
So, in the Automation script you do need to adhere to the case.
So, I just change things to work directly with GUID string from project item like
Image diagramImage = _eaProjectInterface.GetDiagramImage(diagram.DiagramGUID, _logger);
and function now look like this
public static Image GetDiagramImage(this Project projectInterface, string eaDiagramGuid, ApplicationLogger _logger)
{
Image diagramImage;
try
{
var diagramByGuid = projectInterface.GUIDtoXML(eaDiagramGuid);
string tempFilename = string.Format("{0}{1}{2}", Path.GetTempPath(), Guid.NewGuid().ToString(), ".png");
bool imageToFileSuccess = projectInterface.PutDiagramImageToFile(diagramByGuid, tempFilename, FileExtensionByName);
if (imageToFileSuccess)
{
using (var imageStream = new MemoryStream(File.ReadAllBytes(tempFilename)))
{
diagramImage = Image.FromStream(imageStream);
}
File.Delete(tempFilename);
}
else
{
throw new Exception(string.Format("Image to file exprot fail {0}", projectInterface.GetLastError()));
}
}
catch (Exception e)
{
throw;
}
return diagramImage;
}
So, this means that Sparx EA *.FEAP project GUIDs are NOT really GUIDs but just string-keys (as I assume).
Be careful when your work with them :-)
I'm encountering some odd errors in Visual Studio and can't find head or tail. I'm coding some backend in C# which contacts a third party API to retrieve data. The code in question, a single class, is part of a larger solution, but must be the problem as the errors encountered does not occur when not using this class.
Computer setup:
Visual Studio 2013, update 4
Windows 10, Preview Build 10041
Errors encountered
Yesterday the application started behaving weird when debugging it.
The first error I don't remember exactly, but it was something along the lines of "bad" or "corrupted memory".
Without altering the program, I could also encounter a FatalExecutionEngineError exception, which would be thrown immediately after trying to run the program (It didn't make it to the first breakpoint, which was on the first line in the Main entry of the program. Weird!
EDIT: Looks like this:
Managed Debugging Assistant 'FatalExecutionEngineError' has detected a problem in 'PathRedacted\whatsfordinner\whatsfordinner\bin\Debug\whatsfordinner.vshost.exe'.
Additional information: The runtime has encountered a fatal error. The address of the error was at 0x613e4379, on thread 0x11ac. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.
In the end I rebooted my computer since it was all very strange. Problem solved until today.
Now I can't seem to run the program at all; Upon running the program, vshost32.exe just crashes. I don't get any error messages or anything to hint at where the issue is.
Troubleshooting steps
Rebooted my computer - No change, vshost32.exe crashes upon execution
Outcommented the two lines where the class in question was used - Program runs fine.
Tried starting the program as "Release" rather than "Debug". - Program seems to run fine, although I can't test it to the end. (The class is not entirely done yet, and I don't want to spam the API in question)
Tried running the program on another computer running Windows 7 and Visual Studio 2012. - Program seemed to run fine.
At this point I'm pretty lost. I have little idea as to where the issue might be. The source code unfortunately consists of nearly 200 lines, but as I have no clue, I am posting it all.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Specialized;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
namespace whatsfordinner {
public class eTilbudRetriever {
//Web method names
readonly String Get = "GET";
readonly String Post = "POST";
readonly String Update = "UPDATE";
readonly String Delete = "DELETE";
//Parameter identifiers
readonly String ParamApiKey = "api_key";
readonly String ParamLatitude = "r_lat";
readonly String ParamLongitude = "r_lng";
readonly String ParamRadius = "r_radius";
readonly String ParamLimit = "limit";
readonly String ParamOffset = "offset";
//Parameter values
String Latitude = "57.051188"; //Aalborg coordinates
String Longitude = "9.922371";
String Radius = "800000"; //Radius in meters (800km)
String Limit = "48"; // Results per query
//Custom header identifiers
readonly String HeaderXToken = "X-Token";
readonly String HeaderXSignature = "X-Signature";
//Custom header values
readonly String ContentType = "application/json";
//Web Addresses
readonly String HostAddress = "https://api.etilbudsavis.dk/v2/";
readonly String Sessions = "sessions";
readonly String Stores = "stores";
readonly String Offers = "offers";
readonly String Dealers = "dealers";
//Keys
readonly String ApiKey = "<Redacted>";
readonly String ApiSecret = "<Redacted>";
String XToken; //Same as a Session Token in documentation
String XSignature; //Same as a Session Signature in documentation
public eTilbudRetriever() {
//Create a body consisting of the API key
List<KeyValuePair<String, String>> body = new List<KeyValuePair<String, String>>();
body.Add(new KeyValuePair<String, String>(ParamApiKey, ApiKey));
//Send request to create a new session
String response = SendWebRequest(Post, Sessions, body);
//Get the Session Token from the response
dynamic json = JObject.Parse(response);
XToken = json.token;
//Save the Session Signature as well (SHA256 version of API Secret combined with Session Token)
XSignature = ConvertToSha256(ApiSecret + XToken);
}
public void GetDealersList() {
GetList(Dealers);
}
public void GetStoresList() {
GetList(Stores);
}
public void GetOffersList() {
GetList(Offers);
}
private void GetList(string target) {
List<String> resultSet = new List<String>();
String result;
int offset = 0;
//Add desired parameters as headers for the eTilbudsavisen API
List<KeyValuePair<String, String>> query = new List<KeyValuePair<String, String>>();
query.Add(new KeyValuePair<String, String>(ParamLatitude, Latitude));
query.Add(new KeyValuePair<String, String>(ParamLongitude, Longitude));
query.Add(new KeyValuePair<String, String>(ParamRadius, Radius));
query.Add(new KeyValuePair<String, String>(ParamLimit, Limit));
query.Add(new KeyValuePair<String, String>(ParamOffset, offset.ToString()));
//Retrieve a result through the request
result = SendWebRequest(Get, target, query);
/*
* If result is valid, add it to the set of valid results.
* Keep sending requests and increase the offset to avoid duplicated results
* Stop when returned results are no longer valid
*/
while (!String.IsNullOrEmpty(result)) {
resultSet.Add(result);
offset += Int32.Parse(Limit);
query[query.Count-1] = new KeyValuePair<String, String>(ParamOffset, offset.ToString());
result = SendWebRequest(Get, target, query);
}
}
private String SendWebRequest(String method, String extension, List<KeyValuePair<String, String>> arguments) {
try {
String finalAddress = HostAddress + extension;
//Add query to Address (if applicable)
if (method.Equals(Get)) {
finalAddress += '?';
finalAddress += arguments[0].Key + '=' + arguments[0].Value;
for (int i = 1; i < arguments.Count; i++) {
finalAddress += '&' + arguments[i].Key + '=' + arguments[i].Value;
}
}
//Create request and set mandatory header properties
var request = (HttpWebRequest)WebRequest.Create(finalAddress);
request.Method = method;
request.ContentType = ContentType;
request.Accept = ContentType;
//If a Session Token and Signature are available (= After session create), add as headers
if (!String.IsNullOrEmpty(XToken)) {
request.Headers.Add(HeaderXToken, XToken);
request.Headers.Add(HeaderXSignature, XSignature);
}
//Create JSON string containing the desired body arguments (if applicable)
if (method.Equals(Post)) {
//Write body to API
using (var writer = new StreamWriter(request.GetRequestStream())) {
writer.Write(MakeJsonBody(arguments));
}
}
//get response as a JSON object in string format
var response = (HttpWebResponse)request.GetResponse();
return new StreamReader(response.GetResponseStream()).ReadToEnd();
} catch (UriFormatException e) {
Console.WriteLine(e.ToString());
return null;
} catch (WebException e) {
Console.WriteLine(e.ToString());
return null;
}
}
private String ConvertToSha256(String text) {
byte[] bytes = Encoding.UTF8.GetBytes(text);
SHA256Managed hashstring = new SHA256Managed();
byte[] hash = hashstring.ComputeHash(bytes);
string hashString = string.Empty;
foreach (byte x in hash) {
hashString += String.Format("{0:x2}", x);
}
return hashString;
}
private String MakeJsonBody(List<KeyValuePair<String, String>> arguments) {
String json = "{";
foreach (KeyValuePair<String, String> kv in arguments) {
json += "\"" + kv.Key + "\": \"" + kv.Value + "\"";
if (arguments.IndexOf(kv) != arguments.Count() - 1) {
json += ", ";
}
}
json += "}";
return json;
}
}
}
In Main, this is what is executed in relation to the class. The program runs fine when removing these lines from the solution.
eTilbudRetriever retriever = new eTilbudRetriever();
retriever.GetDealersList();
Windows 10, Preview Build 10041
That's the only cue to the possible reason why your program is crashing like this. There are no other ones, your code doesn't do anything dangerous and Newtonsoft.Json has been slammed every possible way by millions of programs. You are using beta versions of both the .NET Framework (v4.6) and the operating system. Thanks on behalf of all Microsoft customers to help debug this new software, your problem is not one that we'll have to troubleshoot. Hopefully, FEEE crashes are exceedingly nasty and hard to debug.
What you are supposed to do is submit a minidump of the crashed process to Microsoft so they can fix the underlying bug. Whatever it might be, there are no cues in your question. Maybe it is the complete rewrite of the x64 jitter (project code name RyuJit). The odds that it has no bugs right now are very slim and such a bug can certainly crash your program like this. That's just a wild guess though.
Microsoft makes these previews available at no cost. Their underlying intention is to get the bugs out before the product ships. Should happen somewhere around the summer. Only real way they can have some confidence that their Support phone lines are not going to get overloaded once they ship the product. The beta updates come fast and furious, there have been 6 CTP versions of .NET 4.6. Quite unprecedented, there usually are no more than 3. At least part of it is the beta for VS2015, lots and lots of new stuff in that release. Which you are not using, that doesn't help either.
Your role in this is one as an unpaid beta-tester. This tends to be rather incompatible with your other role, a programmer that makes a living writing and debugging code. Your code, not somebody else's. When you can't afford to be bogged-down like this then the only sensible thing to do is to unsubscribe from that beta program. Restore your machine to a known-good version of the framework and the operating system. Right now that's .NET 4.5.2 and Windows 8.1
This is my first attempt in using a card reader in C#, or basically anywhere.
I use ACS ACR122U PICC Interface 0 reader in Windows 7 64bit.
My first problem occurs when I tried to connect to the reader using
ModWinsCard.SCardConnect(hContext, cbReader.SelectedItem.ToString(), ModWinsCard.SCARD_SHARE_DIRECT, 0, ref hCard, ref Protocol);
It returns error code 6, but I googled and solved it by changing project's platform from Any CPU to X86.
Right after that I bumped to another issue, this time in controlling the reader.
I tried with :
_sentBuffer = new byte[]
{
0xFF,
0x00,
0x48,
0x00,
0x00
};
_receivedBuffer = new byte[10];
_receivedBuffer[0] = 0;
_returnCode = ModWinsCard.SCardControl(_hCard, _dwControlCode, ref _sentBuffer[0], _sentBuffer.Length, ref _receivedBuffer[0], _receivedBuffer.Length, ref bytesReturned);
The returned code is 1, which is weird because I can't found it in the documentation.
Really need a hand in this.
Thanks !
Doing some research myself about working with SCardControl and found I was getting the same return value of 1.
I found a list of Error Codes here which then states the below.
"Note Some return values may have the same value as existing Windows return values that signify a similar condition. For information about error codes not listed here, see System Error Codes."
And that documentation states that the error code value 1 is ERROR_INVALID_FUNCTION
I know this question is old but hopefully it will help someone in the future.
I somehow have it solved by downloading the latest driver from the provider's website, with uninstalling the driver that is included in the driver CD.
Still wonder what does return 1 means though..
I know this is an old topic, but I have the same problem on Windows 10 (x64), except I'm using VB6.
I have a lot working through using SCardTransmit etc, I can controle/read/write if there's a card on it. But I want to control the reader (ACR112U) without a card (turn off autodetection/beep) and that's only possible using SCardControl (as far as I know), cause when I connect with Directmode and then call our SetBuzzerCardDetection to turn it off, I get a ERROR_BAD_COMMAND, but when shared and a card it works.
Even the example from ACS themselves with IOCTL_GET_VERSIONS gives me return value ERROR_INVALID_FUNCTION
Dim vcVersion As VERSION_CONTROL
Dim lReturnedLength As Long
m_lResult = SCardControl(m_hCard, _
IOCTL_GET_VERSIONS, _
0, 0, _
vcVersion, 20, _
lReturnedLength)
If m_lResult <> SCARD_S_SUCCESS Then
I'm using the following
Declare Function SCardControl Lib "WinScard.dll" ( ByVal hCard As Long, ByVal dwControlCode As Long, ByRef lpInBuffer As Any, ByVal lSizeofBuffer As Long, ByRef lpReceiveBuffer As Any, ByVal lpReceiveBufferSize As Long, ByRef lpBytesReturned As Long) As Long
Const IOCTL_CCID_ESCAPE As Long = (&H42000000 + 3500)
'hCard is a valid handle returned by SCardConnect
'lReturn = SCardConnect(hContext, sReader, eShareMode, ePreferredProtocol, hCard, eActiveProtocol)
'With card on reader: eShareMode = SCARD_SHARE_SHARED, ePrefferedProtocol = SCARD_PROTOCOL_Tx
'Without card on reader: eShareMode = SCARD_SHARE_DIRECT, ePrefferedProtocol = SCARD_PROTOCOL_UNDEFINED
Dim abIn() As Byte
Dim abOut() As Byte
Dim lInLength As Long
Dim lOutLength As Long
Dim lReturn As Long
Dim lReturnedLength As Long
'Command for turning off Buzzer output during card detection
lInLength = 5
ReDim abIn(lInLength - 1)
abIn(0) = &HFF
abIn(1) = &H0
abIn(2) = &H52
abIn(3) = &H0
abIn(4) = &H0
lOutLength = 256
ReDim abOut(lOutLength - 1)
lReturn = SCardControlAny(hCard, _
IOCTL_CCID_ESCAPE, _
abIn(0), lInLength, _
abOut(0), lOutLength, _
lReturnedLength)
'with card on reader: lReturn = ERROR_BAD_COMMAND
'without card on reader: lReturn = ERROR_INVALID_FUNCTION
Mind you for using Escape I also added the ControlEscapeEnable to the registry (just for the sake of it I added it in several places)
First I did everything without loading a special driver (other than what Windows 10 itself already got), but due to Samuel Adam's remark I loaded the latest from ACS website but it didn't make a difference.
It's really driving me crazy, just like it's also driving me crazy that WebUSB doesn't allow it anymore so I would have been able to use a webbased version.
I'm using this snippet of code to output a list of all the computers on my network (the language is jscript.net, but it's just a small manipulation of C#).
var parentEntry = new DirectoryEntry();
parentEntry.Path = "WinNT:";
for(var childEntry in parentEntry.Children) {
if(childEntry.SchemaClassName == "Domain") {
var parentDomain = new TreeNode(childEntry.Name);
this.treeView1.Nodes.Add(parentDomain);
var subChildEntry : DirectoryEntry;
var subParentEntry = new DirectoryEntry();
subParentEntry.Path = "WinNT://" + childEntry.Name;
for(subChildEntry in subParentEntry.Children) {
var newNode1 = new TreeNode(subChildEntry.Name);
if(subChildEntry.SchemaClassName == "Computer") {
parentDomain.Nodes.Add(newNode1);
}
}
}
}
I have 2 issues with this:
1) It is extremely slow. There's about 100 computers showing, and it takes about 1 minute to load.
2) I want to get only a list of computers that are currently online.
This can be done because I've seen other programs doing it and they are much faster, also they're able to show only the ones online.
Am I missing something?
I know it's a bit old, but for others...this snippet will return a 760 computer names from a domain using AD within 2-3 seconds....a significant improvement....enjoy!
Friend Shared Function DomainComputers() As Generic.List(Of String)
' Add a Reference to System.DirectoryServices
Dim Result As New Generic.List(Of String)
Dim ComputerName As String = Nothing
Dim SRC As SearchResultCollection = Nothing
Dim Searcher As DirectorySearcher = Nothing
Try
Searcher = New DirectorySearcher("(objectCategory=computer)", {"Name"})
Searcher.Sort = New SortOption("Name", SortDirection.Ascending)
Searcher.Tombstone = False
SRC = Searcher.FindAll
For Each Item As SearchResult In SRC
ComputerName = Item.Properties("Name")(0)
Result.Add(ComputerName)
Next
Catch ex As Exception
End Try
Return Result
End Function
I would look at Linq To Active Directory found on CodePlex
You'd also have to define "my network". Your subnet? Your Organizational Unit? Your domain? Your forest?
Also consider where your LDAP server is that you are querying. Is it close or is it on the other end of a remote link?
Also what do you consider "online"? Do you expect to be able to ping it? Do you expect to be able to connect to it and perform an operation?
There are many things to consider here. Also if you have other infrastructure components such as an SCCM / SMS server they can often be queried much faster since all of the discovery data has flowed up into the data warehouse.