procedure TfmOrtComm.BtnPortsClick(Sender: TObject);
var S: String;
FriendlyName: String;
Reg: TRegistry;
RegInfo: TRegKeyInfo;
RegValueNames: TStringList;
RegKeyNames: TStringList;
begin
Reg := TRegistry.Create;
RegValueNames := TStringList.Create;
RegKeyNames := TStringList.Create;
Reg.RootKey := HKEY_LOCAL_MACHINE;
S := 'SYSTEM\CurrentControlSet\Enum\USB';
S := S + '\Vid_04d8&Pid_fdcf\0123456789';
If Reg.KeyExists(S) then begin
Reg.OpenKeyReadOnly(S);
Reg.GetKeyInfo(RegInfo);
Reg.GetKeyNames(RegKeyNames);
ErrorListBox1.Items := RegKeyNames;
Reg.GetValueNames(RegValueNames);
ErrorListBox1.Items.AddStrings( RegValueNames );
FriendlyName := Reg.ReadString('FriendlyName');
end;
RegKeyNames.Free;
RegValueNames.Free;
Reg.Free;
end;
I need to clean this up and make it more useful, but this procedure seems
much simpler than another one I found in a previous search. Hopefully there
are no memory leaks or other problems with this code. I was a bit hesitant
to mess with the registry, but I think this is pretty safe. Yet it is very
late and maybe I'll see something after I sleep awhile.
TIA for any corrections, comments, or suggestions. This is new ground for
me.
Paul
I don't get a "FriendlyName" value until I go into another enumeration
hive (USBSTOR) . . .
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR
\Disk&Ven_&Prod_USB_DISK_25X&Rev_PMAP\07540E18005D&0]
<snip>
"FriendlyName"="USB DISK 25X USB Device"
The values I get for a USB/Vid etc you use are . . .
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB
\Vid_0b27&Pid_0601\0000000000319E]
"DeviceDesc"="USB Mass Storage Device"
"LocationInformation"="USB Mass Storage Device"
"Capabilities"
"UINumber"
"HardwareID
"CompatibleIDs"
"ClassGUID"
"Class"="USB"
"Driver"
"Mfg"="Compatible USB storage device"
"Service"="USBSTOR"
"ConfigFlags"
I am running Windows XP Pro SP 2.
Also I'd throw a try/finally resource protection for Reg.
Alan Lloyd
======================================================================
Should the try/finally start with Reg := TRegistry.Create; and the finally
section free everything? Does Free need to check for a "nil" value first?
And I probably should set the pointer to nil after free. D4 does not have
FreeAndNil.
I just used RegEdit and I have many entries under USB. In fact, probably
every device that has ever been enumerated. It appears that some devices,
such as your mass storage device, are further descibed in a separate
USBSTOR hive, as defined by "Service". There are also entries under
USBPRINT, but those do not have friendly names.
I'm running XP Home, and I think it's SP3. I'm trying to get my application
to work also on my laptop which has Vista Business. So far the main
problems seem to be due to folder and file virtual stores which is related
to user file permissions, but that's another story.
Thanks,
Paul
Try-finally blocks should look like this:
AquireResource;
try
UseResource;
finally
ReleaseResource;
end;
The resource in question is a TRegistry object. Aquire it by
constructing a new instance. Release it by calling Free on that instance.
> Does Free need to check for a "nil" value first?
No, you don't need to check whether the variable is nil before calling
Free on it. For one thing, it's always safe to call Free on a nil value.
And besides that, if acquiring the resource fails, the release shouldn't
occur at all. That's how the code pattern above will work.
> And I probably should set the pointer to nil after free.
Why? Are you going to check that variable's value later to see whether
it's equal to nil?
> D4 does not have FreeAndNil.
So what?
There's nothing magical about FreeAndNil. If you need a variable to have
a particular value, then write an assignment statement that gives it
that value.
--
Rob
Within the Free method is essentially . . .
if Self <> nil then
Destroy;
So you do not ever need to check before calling free.
Furthermore any exception in the Create constructor results in the
failed object being set to nil. That's one reason why you don't
include the Create call in the try / finally. Beause if the create
failed, the object would be set to nil, & so any Free would not call
Destroy anyway.
Alan Lloyd
> Ok, but, I don't understand why you need that info? that part of the
> data is suppose to be transparent to COM port activity...
> Real Com ports don't have such ID's
> Unless you have some remote device that is serial linked and you're
> forcing the user to use yours and not a generic name brand USB-Serial
> converter?
> I guess that could be a security dongle of such..
I have a proprietary device that enumerates as a serial port, using a
Microchip PIC18F2450. It then converts the commands to and data from a
second PIC over a digital isolator. Originally I built the device to run
directly on a serial port, but many new computers don't have them, and I
had problems with most off-the-shelf USB-Serial converters. I was able to
use the Silabs CP2103 by adjusting the timeout values for buffer flushing,
but it was difficult to solder the 0.5 mm pitch IC. The Microchip part gave
me more flexibility and provided a learning experience in the inner
workings of USB hardware.
Since I will be building these devices as well as writing the interface
software, I can control all aspects of the design. Mostly I want it to be
easy to install, as my customers are not generally very computer literate.
With the basic serial port, I had no way to determine what COM port was
connected to my hardware except by sending a special control character and
looking for a specific response. This worked OK, but my partner who
distributes the system was worried that other devices might be attached to
other COM ports, and in some cases a certain character might cause unwanted
and even dangerous behavior. So I need to identify the exact COM port that
corresponds to my hardware, and only attempt communication to it.
Verstehen? :)
Paul
Hmm. Ok, how about hand shaking on the CD/Ring inputs? there isn't
tomany devices that do such things .
Normally, specialized wired serial cables are used to cross the CD/RD
from lets say a DRS/DTR line so that it can be ID as being the correct
hardwire interface.
If a roundtrip packet test is considered too dangerous, I guess it goes for
all ways of probing.
Although you don't use the SiLabs chip they have an application note
(AN197.pdf) which has useful notes on accessing the serial port.
MSDN (Microsoft Developer Network) has a section on Communications
Resources which has sub-sections of About Communications Resources,
Using Communications Resources, & Communications Reference. This has
detailed explanations of accessing COMM ports as a file.
I also have some code for accessing a COMM port in that way, which I
could send you (email me).
SparkFun Electronics have a CP2103 breakout card to a serial port to
USB access which might interest you on
http://www.sparkfun.com/commerce/product_info.php?products_id=199
0.5mm spaced IC chips are most likely better attached using an oven -
Elektor magazine had an article & kit to make one a few months ago. (I
think Elektor is now sold in USA).
Alan Lloyd
No it doesn't. The object doesn't exist at all -- construction failed.
Nothing gets set to nil.
> That's one reason why you don't
> include the Create call in the try / finally. Beause if the create
> failed, the object would be set to nil, & so any Free would not call
> Destroy anyway.
The reason you don't put the constructor call inside the try-finally be
because the target of the assignment statement *doesn't* get set to nil.
If it's inside, then a failed constructor causes Free to be called on an
uninitialized variable, and the compiler even tells you so.
--
Rob