The application ZKAccess-3.5 has the ability to enumerate doors, and open or close the selected door.
The sdk has this incomplete API:
VARIANT_BOOL ACUnlock(LONG dwMachineNumber, LONG Delay);
VARIANT_BOOL GetDoorState(LONG MachineNumber, [in,out] LONG* State, [out,retval] VARIANT_BOOL* pVal);
How do I select the door I want to open/close? I have 2 doors. I expected a doorID parameter or something like that.
Device: inBio 260 / 2 doors
EDIT: PullSDK Wrapper in C#, Shows how to use PullSDK
Those functions are not a part of the PullSDK.
ZKTeco claims the standalone SDK includes PullSDK when It does not cover everything (example: ControlDevice function).
The native dll plcommpro.dll is the main dll for the PullSDK.
It exports the function ControlDevice, that can be used to lock/unlock doors, but the documentation is confusing, I'm not sure how to use it, I will try to decompile ZKAccess3.5 to find that out.
int ControlDevice(HANDLE handle, LONG OperationID, LONG Param1, LONG Param2, LONG Param3, LONG Param4, const char *Options)
ZKTeco is not good at what it does (hardware, software, protocols, sdk, docs).
Related
I'm trying to import winmm.dll on a WP8.1 app to try and control device volume. Based on research from Google, I have created a Windows Runtime Component to wrap the actual function call, and then I call this from the main app. Since the issue is clearly in the wrapper, here's the code:
public sealed class VolumeControl
{
[DllImport("winmm.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode)]
internal static extern int waveOutSetVolume(IntPtr uDeviceID, int dwVolume);
public static void Set(int volume)
{
// get volume as proportion of maximum
double newVolume = ushort.MaxValue * volume / 10.0;
// convert this into volume for two channels
uint v = ((uint)newVolume) & 0xffff;
uint vAll = v | (v << 16);
// set volume
waveOutSetVolume(IntPtr.Zero, (int)vAll);
}
I have also enabled unsafe code in the wrapper's project properties. DllImport is possible for native libraries in WP8.1, as far as I understand. I don't expect this app to pass certification on the Windows Store, but still I can't see why this code wouldn't work on a developer unlocked device.
Any idea if I've missed something here?
On Windows Mobile, all waveform audio function are implemented in 'coredll.dll'. Use this DLL instead of 'winmm.dll'.
The documentation has the answer:
Requirements
Minimum supported client
Windows 2000 Professional [desktop apps only]
In other words this function is not available from Windows Store app.
Turns out that WP8.1 has a WinMMBase.dll rather than plain old winmm.dll.
I found this by running a web server hack to browse the System32 folder (see xda-developers). After downloading the dll and inspecting it with DLL Export (http://www.nirsoft.net/utils/dll_export_viewer.html), I found that it does have the waveSetOutVolume function. The function itself doesn't seem to affect the volume though, but that wasn't the point of the question I guess :)
I'm making a windows form application using Visual Studio. The application allows you to enter the what you want the photo to be named, and then saves that image to a specific location on the network. It works great when I use it on my laptop. However, when I try to run it on the a desktop, it does not work. Instead I get the message:
System.Runtime.InteropServices.COMException (0x80040217): No
combination of intermediate filters could be found to make the
connection.
at DirectShowLib.DsError.ThrowExceptionForHR(Int32 hr)
at OrderProductCapture.Capture.SetupGraph(DsDevice dev, Int32 iWidth,
Int32 iHeight, Int16 iBPP, Control hControl)
at OrderProductCapture.Capture.ctor(Int32 iDeviceNum, Int32 iWidth,
Int32 iHeight, Int16 iBPP, Control hControl)
at OrderProductCapture.frmMain.ctor()
The Call Stack says:
OrderProductCapture.exe!OrderProductCapture.Capture(int iDeviceNum, int iWidth, int iHeight, short iBPP, System.Windows.Forms.Control hControl) Line 82
OrderProductCapture.exe!OrderProductCapture.frmMain.frmMain() Line 50
OrderProductCapture.exe!OrderProductCapture.Program.Main() Line 19
I have already googled this many times, and I've looked at most of the similar questions on SO. Both computers are using Windows 7 professional. Any help would be fantastic.
This is the code where my code catches the exception. I do not think the code is wrong, because it works fine on my laptop.
public Capture(int iDeviceNum, int iWidth, int iHeight, short iBPP, Control hControl)
{
DsDevice [] capDevices;
// Get the collection of video devices
capDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
if (iDeviceNum + 1 > capDevices.Length)
{
throw new Exception("No video capture devices found at that index!");
}
try
{
// Set up the capture graph
SetupGraph( capDevices[iDeviceNum], iWidth, iHeight, iBPP, hControl);
// tell the callback to ignore new images
m_PictureReady = new ManualResetEvent(false);
}
catch
{
Dispose();
throw;
}
}
When having to convert between media formats, you can programmatically force it to use some specific filter chain and configure it tightly to your needs, but DirectSHOW also has the ability of "guessing" the right tools to use. It knows all the tiny media handlers that are oficially installed in the OS, and tries to match them so that final required "conversion" is built.
However, DirectShow still needs those tiny converters to be installed. DS is able to analyze and connect them, but will not provide you any support for exotic media types. Often, even non-exotic can be problematic if the OS is "fresh-n-clean".
If I remember correctly, that error basically means that (on this problematic machine) some "codecs" are missing.
These things often come with any:
drivers for webcams/microphones/soundcards
audio-processing software (sound editors, media recorders, media players, ..)
"codec packs" like CCCP (really, don't get confused by their logo)
specific codec/filter packages
(...)
First thing I'd now do would be:
recall what I tried to convert
try to read all error messages and logs and find out if there's some faulty filter mentioned, maybe it needs reinstalling
compare what audio-related software is installed on machines where the program WORKS versus the problematic machine
basing on the above, try to deduce what codec is missing
find it, download, install
Also, you may read the code of SetupGraph() function. I bet there's a clear reference to the format that is being used, and this may point out what codec is missing.
Codecs also sometimes get damaged (actually not themselves, but their configuration and registration entries may get damaged). If you are sure that the correct codecs are available on the machine, reinstalling or "repairing" (if they have such option) them can help.
I am looking for a way to reliably detect when I boot into WinPE 4 (powershell) (or WinPE 3 (vbs) as an alternative), have I booted from a UEFI or BIOS System? (without running a third party exe as I am in a restricted environment)
This significantly changes how I would be partitioning a windows deployment as the partitions layout changes and format. (GPT vs. MBR, etc)
I have one working that is an adaptation of this C++ code in powershell v3 but it feels pretty hack-ish :
## Check if we can get a dummy flag from the UEFI via the Kernel
## [Bool] check the result of the kernel's fetch of the dummy GUID from UEFI
## The only way I found to do it was using the C++ compiler in powershell
Function Compile-UEFIDectectionClass{
$win32UEFICode= #'
using System;
using System.Runtime.InteropServices;
public class UEFI
{
[DllImport("kernel32.dll")]
public static extern UInt32 GetFirmwareEnvironmentVariableA([MarshalAs(UnmanagedType.LPWStr)] string lpName, [MarshalAs(UnmanagedType.LPWStr)] string lpGuid, IntPtr pBuffer, UInt32 nSize);
public static UInt32 Detect()
{
return GetFirmwareEnvironmentVariableA("", "{00000000-0000-0000-0000-000000000000}", IntPtr.Zero, 0);
}
}
'#
Add-Type $win32UEFICode
}
## A Function added just to check if the assembly for
## UEFI is loaded as is the name of the class above in C++.
Function Check-IsUEFIClassLoaded{
return ([System.AppDomain]::CurrentDomain.GetAssemblies() | % { $_.GetTypes()} | ? {$_.FullName -eq "UEFI"}).Count
}
## Just incase someone was to call my code without running the Compiled code run first
If (!(Check-IsUEFIClassLoaded)){
Compile-UEFIDectectionClass
}
## The meat of the checking.
## Returns 0 or 1 ([BOOL] if UEFI or not)
Function Get-UEFI{
return [UEFI]::Detect()
}
This seems pretty over the top just to get a simple flag.
Does anyone know if there is there a better way to get this done?
It is no less hacky, in the sense it will still require interop from powershell, but the interop code might be neater if you use (or can call): GetFirmwareType().
This returns a FIRMWARE_TYPE enumeration documented here. I can't believe given both functions are introduced in Windows 8 and exported by kernel32.dll that Microsoft's own documentation points you at "using a dummy variable"!
Internally, GetFirmwareType calls NtQuerySystemInformation. I will dig into what it is doing, but I do not think it is necessarily going to be enlightening.
Unfortunately, this only works for PE4 (Windows 8) since these functions were only added then.
The easieast way by far is to run on PowerShell:
$(Get-ComputerInfo).BiosFirmwareType
This may be a little late, but if one knows they are running in WinPE, the following code should work:
$isuefi = (Get-ItemProperty -Path HKLM:\System\CurrentControlSet\Control).PEFirmwareType -eq 2
$env:firmware_type
Not sure since what version this is supported.
Returns UEFI and Legacy in my tests.
However this is on full installation, Have note confirmed existence in WinPE
It looks like the PE environment has a folder that is specific to the PE environment. In addition, the variable %TargetDir% is described here, TARGETDIR property.
Lastly, you could check if you are running from X: There should be also a folder that has the boot.wim image you can check for. I believe the path would be X:\Sources\Boot.wim but double check.
if ( Test-Path "%TargetDir%\Windows\wpeprofiles" ) {
Write-host "You're in Windows PE"
}
I don't know if this will help (based on C# solution), but:
Win32_DiskPartition has the properties "Bootable" (bool), "BootPartition" (bool), and "Type" (string). For my UEFI system, "Type" comes back as the string "GPT: System".
Now, for all Win32_DiskPartitions that are bootable, are a boot partition, and have the specified type, determine if any of them are internal.
Hope this helps.
To sum it up, I need to do this:
12345(hWnd) -> "C:\setup.exe"
Right now, I am using GetProcessImageFileName to retrieve the Kernel Device Path of a process handle. I'm retrieving the handle using OpenProcess, passing it the PID. The PID (which I also need) is being retrieved using GetWindowThreadProcessId.
However, this gets me to a string like:
\Device\Harddisk1\setup.exe
At this point, I enumerate all drives on the system using DriveInfo.GetDrives(), and then call QueryDosDevice. Finally, I can do some string-manipulation magic, and "boom," I have my path.
Ok, so my issues:
This process breaks down on Network drives.
All I really want is QueryFullProcessImageName on XP
There HAS to be a better way to do this. Please enlighten me, oh gods of WIN32API!
The obvious question would be why you don't just use QueryFullProcessImageName, if that's what you want? Do you need compatibility with older versions of Windows?
The closest equivalent to QueryFullProcessImageName that's available on XP is probably GetModuleFileNameEx. I'd probably detect whether QueryFullProcessImageName is available and use it if possible, otherwise fall back to GetModuleFileNameEx.
Edit: While GetModuleFileNameEx isn't 100% dependable at retrieving the name of the executable for every possible process, it does work at least a fairly substantial part of the time. Here's a quick bit of test code I put together:
#include <windows.h>
#include <psapi.h>
#include <iterator>
#include <iostream>
#include <string>
#include <map>
std::string getfilename(DWORD pid) {
HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid);
static int winver;
char path[256]= {0};
DWORD size = sizeof(path);
if (winver==0)
winver = GetVersion() & 0xf;
#if WINVER >= 0x600
if (winver >= 6)
QueryFullProcessImageName(process, 0, path, &size);
else
#endif
if (!GetModuleFileNameEx(process, NULL, path, sizeof(path)))
strcpy(path, "Unknown");
return std::string(path);
}
typedef std::map<DWORD, std::string> win_map;
namespace std {
ostream &operator<<(ostream &os, win_map::value_type const &v) {
return os << v.first << ": " << v.second;
}
}
BOOL CALLBACK show_info(HWND window, LPARAM lParam) {
win_map &exes = *(win_map *)lParam;
DWORD pid;
GetWindowThreadProcessId(window, &pid);
exes[pid] = getfilename(pid);
return true;
}
int main() {
win_map exes;
EnumWindows(show_info, (LPARAM)&exes);
std::copy(exes.begin(), exes.end(), std::ostream_iterator<win_map::value_type>(std::cout, "\n"));
return 0;
}
The results of a quick test are somewhat interesting. Compiled as 32-bit code, the version using QueryFullProcessImageName found 33 processes with top-level windows, and found names for 31 of those executables. The version using GetModuleFileNameEx, also found 33 processes, but only found names for 21 of the executable. If, however, I compile it as 64-bit code, either version finds filenames for 31 out of 33 executables (and the same two fail). Given the frequency with which you see XP/x64, that's probably of little consequence, but I found it interesting nonetheless.
In any case, even the least capable version (32-bit/GMFNE) found names for ~2/3rds of the files. While that's certainly not what you'd hope for, it's certainly better than nothing.
It must be possible to retrieve the file path to running processes since Sysinternals' Process Explorer does it. Of course, Process Explorer uses NtQueryInformationProcess, which isn't a supported function. (On the other hand, since you're specifically targeting XP and would use QueryFullProcessImageName on Vista and later, the fear of the API becoming unavailable in a future version of Windows is probably not a concern.)
CodeProject has an article about how to use NtQueryInformationProcess.
Does anyone have any idea how to track the signal strength of a bluetooth connection perferably in C#?
I was thinking using a WMI query but couldn't track down the WMI class encapsulating the connection.
The idea is when I leave my machine with my cellphone in pocket the bluetooth signal weakens and my machine locks and I don't get goated.
The Link Manager Protocol (LMP) running in a Bluetooth device looks after the link setup and configuration. This is all done by two devices exchanging Protocol Data Units (PDUs).The hardware and software functionality of the RSSI is provided at the LMP level that permits you to manage the RSSI Data. It allows you to read the RSSI level and control the TX RF output power (the LMP power commands) LMP for control and to get at status information.
So what you are actually looking for is defined in the LMP when using the MS Bluetooth stack.
The MS Bluetooth Stack HCI interface already supports functions below i.e
HCI_READHCIPARAMETERS
HCI_STARTHARDWARE
HCI_STOPHARDWARE
HCI_SETCALLBACK
HCI_OPENCONNECTION
HCI_READPACKET
HCI_WRITEPACKET
HCI_CLOSECONNECTION
I suppose microsoft could have implemented a function called HCI_Read_RSSI but they didn't.
To obtain the the RSSI data you will have to use the LMP to get the info you need.
Example psuedocode to read RSSI Data
// Read HCI Parameters
#include <windows.h>
#include <windev.h>
#include <bt_buffer.h>
#include <bt_hcip.h>
#include <bt_os.h>
#include <bt_debug.h>
#include <svsutil.hxx>
#include <bt_tdbg.h>
unsigned short hci_subversion, lmp_subversion, manufacturer;
unsigned char hci_version, lmp_version, lmp_features[8];
if (BthReadLocalVersion (&hci_version, &hci_subversion, &lmp_version, &lmp_subversion, &manufacturer, lmp_features) != ERROR_SUCCESS) {
SetUnloadedState ();
return 0;
}
WCHAR szLine[MAX_PATH]
unsigned char *pf = lmp_features;
if ((*pf) & 0x02) {
wsprintf (szLine, L" RSSI");
}
This will ONLY work with the Microsoft bluetooth stack. This is C++ code also. I got this from the experts exchange post(I know) at the bottom of the page.
http://www.experts-exchange.com/Programming/Wireless_Programming/Bluetooth/Q_21267430.html
There is no specific function that does it for you.
Also there is this library that may help you, I haven't looked through the documentation completely but I've heard good things about it.
http://inthehand.com/content/32feet.aspx
Goodluck man!