DiskPart “Attribute Volume” Object Not Found

The title isn’t very pretty, but it gets the point across.  I had a weirdly partitioned computer come in to my shop, and I needed to make corrections.  The last issue I confronted was that the Recovery partition had a drive letter… it shouldn’t.  The user shouldn’t see it at all, normally.  But when I tried

attribute volume set nodefaultdriveletter

I was presented with an “Object Not Found” message.  I searched for a solution but could not find one; I was about to give up when I had an idea.

(Note that the drive in question was a Basic disk.  This likely doesn’t work the same way for Dynamic disks; I haven’t tried it so I can’t say for sure.)

First, I did:

select partition <x>

where <x> was the partition for the C: drive.  Then I did:

detail partition

I highlighted and copied the GUID after the Type: heading and pasted it into a notepad window.  I then selected the “problem” partition and did the same thing, so that now I knew both of the Type ID values.  Then, with the problem partition still selected I did:

set id=<drive-C-type>

Now I was able to fix the volume:

select volume <problem-partition>

attribute volume set nodefaultdriveletter

This time it worked.  Finally, I made sure the problem partition was still selected and did:

set id=<problem-partition-type>

to put the partition back to the correct type.

Rebooted just to make sure, and all was well.

Pythonic Windows Printing

Way back when, circa 2006 or so, I was writing an application for a customer in Python.  It needed to be able to print, as many applications do, and so I thought “how hard could it be?”

Well, it took a lot of head-scratching and code-diving before I understood how to do it right.  It was such a pain that I decided to write an article about how to print from Python on Windows; eventually I added my own module, MSWinPrint.py, to make it easier.

Time has moved on and the site where I originally shared this is kinda creaky and may be about to be canned.  So here is the original article, with basically no changes.

The module MSWinPrint.py can be downloaded from my Github page, or you can get it via PyPI.

So without further ado, here’s the original article:

Note: The following instructions are supplied without warranty. If you use them, you are accepting responsiblity for anything that might go wrong. Also note that the instructions below have been tested on Python 2.4 on Windows XP only (usingpywin32 build 205 and later).

So you want to produce some output? On the surface it sounds pretty simple:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# create a dc (Device Context) object (actually a PyCDC)
dc = win32ui.CreateDC()

# convert the dc into a "printer dc"

# leave out the printername to get the default printer
# automatically
dc.CreatePrinterDC(printername)

# you need to set the map mode mainly so you know how
# to scale your output.  I do everything in points, so
# setting the map mode as "twips" works for me.
dc.SetMapMode(win32con.MM_TWIPS) # 1440 per inch

# here's that scaling I mentioned:
scale_factor = 20 # i.e. 20 twips to the point

# start the document.  the description variable is a string
# which will appear in the print queue to identify the job.
dc.StartDoc(description)

# to draw anything (other than text) you need a pen.
# the variables are pen style, pen width and pen color.
pen = win32ui.CreatePen(0, int(scale_factor), 0L)

# SelectObject is used to apply a pen or font to a dc.
dc.SelectObject(pen)

# how about a font?  Lucida Console 10 point.
# I'm unsure how to tell if this failed.
font = win32ui.CreateFont({
    "name": "Lucida Console",
    "height": int(scale_factor * 10),
    "weight": 400,
})

# again with the SelectObject call.
dc.SelectObject(font)

# okay, now let's print something.
# TextOut takes x, y, and text values.
# the map mode determines whether y increases in an
# upward or downward direction; in MM_TWIPS mode, it
# advances up, so negative numbers are required to
# go down the page.  If anyone knows why this is a
# "good idea" please email me; as far as I'm concerned
# it's garbage.
dc.TextOut(scale_factor * 72,
    -1 * scale_factor * 72,
    "Testing...")

# for completeness, I'll draw a line.
# from x = 1", y = 1"
dc.MoveTo((scale_factor * 72, scale_factor * -72))
# to x = 6", y = 3"
dc.LineTo((scale_factor * 6 * 72, scale_factor * 3 * -72))

# must not forget to tell Windows we're done.
dc.EndDoc()

So far, so good. Doing it this way gives you decent output, but you can’t change the paper size or orientation (or a bunch of other things).

It turns out that both win32ui and win32gui have a CreateDC function, but they are NOT equivalent. win32ui.CreateDC gives you a PyCDC object (wrapping an hDC and various methods for manipulating it), but win32gui.CreateDC gives you an integer hDC value. BUT… win32ui.CreateDC doesn’t allow you full access to configure the hDC (or if it does, I couldn’t figure out how to use it). So you can’t make those changes you’d like to make if you get the DC the way I did above.

SO… here’s another version. This is just the beginning of the text above; the whole procedure involves opening the printer, configuring it, getting an integer hDC for the configured printer, and making a PyCDC out of it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# if you just want to use the default printer, you need
# to retrieve its name.
printer = win32print.GetDefaultPrinter()

# open the printer.
hprinter = win32print.OpenPrinter(printer)

# retrieve default settings.  this code does not work on
# win95/98, as GetPrinter does not accept two
devmode = win32print.GetPrinter(hprinter, 2)["pDevMode"]

# change paper size and orientation
# constants are available here:
# http://msdn.microsoft.com/library/default.asp?
#      url=/library/en-us/intl/nls_Paper_Sizes.asp
# number 10 envelope is 20
devmode.PaperSize = 20
# 1 = portrait, 2 = landscape
devmode.Orientation = 2

# create dc using new settings.
# first get the integer hDC value.
# note that we need the name.
hdc = win32gui.CreateDC("WINSPOOL", printer, devmode)
# next create a PyCDC from the hDC.
dc = win32ui.CreateDCFromHandle(hdc)

# now you can set the map mode, etc. and actually print.

Hopefully this helps someone else.

Technical Support Scams

Lately I’m hearing from a lot of my customers about technical support scams.  These scams prey upon average users with limited technical knowledge, and can become pricey for the victims.

There are three different ways these scams may start:

The first way is by means of hijacking your web browser.  (Actually, it’s a remote website that is hijacked, but stay with me here.)  Say one day you are surfing around, looking for information about remote controlled cars or nursing homes or movies (or anything, really), and suddenly you have a scary message on your screen…  Windows Virus Warning! or 149 Viruses Detected or something like that.  The message warns that you should not shut down or restart the computer, and in large print there is a phone number that you are told to call for help.  So you pick up the phone and dial…

OR perhaps you are already having a problem with your computer.  Let’s say you have a Dell computer, and it’s not working right, so you do a search on the Internet for “Dell support.”  Right there at the top of the page of search results is one that says Dell Support followed by a phone number.  If you look carefully, it says “AD” next to the listing, but maybe you don’t notice, or the fact that it’s an advertisement doesn’t bother you (it should).  So once again, you pick up the phone and start dialing…

OR MAYBE you aren’t even at your computer, but your phone rings.  The guy (it’s usually a man) on the phone tells you he’s with Microsoft, or Norton, or some other famous technology company, and that they have determined that your computer is infected with something nasty…

All of the above situations end up the same way… you’re on the phone with someone who says he is a tech support specialist who wants to help you with your problem.  As you are reading this, you’ve probably figured out by now that he’s lying, but sadly in real life too many people are taken in this way.

From this point, the script is much the same, regardless of how you got here.  The tech tells you he needs you to give him access to your computer.  He guides you to his website, where he helps you download and run the remote control software.  Now he has control of your computer, and he begins a classic confidence game.  He shows you legitimate files in your computer’s file system or messages in the event viewer or other technical things that you don’t know how to interpret, and tells you that they are signs of a terrible infection (or less commonly, other technical problems with impressive-sounding names).  Fortunately, the tech can help you with this awful situation… you just have to pay him first.

Yes, of course, it’s about money.

If you have gotten caught by this kind of scam, the first thing you need to do is to have your computer looked at by a real technician.  Someone you trust.  Remember, you let the bad guy have control of your computer.  You ran software you got from his website.  He could have done anything to your computer… installed spyware, for instance.  In my experience, I haven’t seen this happen very often; most of these guys are just in it for the cash payoff, and if they can’t get money out of you, they move on to the next victim.  But it does happen, and if you do anything more with your computer than watch Youtube, you really should have it looked at.

More importantly, if you have any of the experiences I’ve described above, be careful!  Never call a phone number just because it pops up on the screen!  If you get a phone call where the caller says your computer is infected, I recommend you say “Thanks!  I’ll get my computer looked at right away!” and then hang up the phone before he can say another word.  If you’re looking for technical support with your computer, be really sure that you have a good phone number before you call.  Better yet, call someone local for support, even if you have a big name brand computer.

The scammers are out there, and they’re always looking for someone to take advantage of.  Don’t be their next victim.

Toner In The Carpet (Oh No!)

Yesterday while evaluating a printing issue with a customer’s color Lexmark laser printer, I managed to drop the black developer unit on the floor.  It left a quarter-sized spot of purest blackness, then spread a gray cast over dinner-plate-sized area nearby when it bounced.  Ack.

I looked up the best ways to clean up that sort of mess and found several sites that recommended dry cleaning solvent, which I did not have, followed (if needed) by water with dish detergent added.  Messy procedures that would require me to go out and buy things.  I was pretty sure there was no place in the city of Edina to buy dry cleaning solvent anyway.

I apologized profusely to the secretary whose office I had just sullied; she acted cool about it, but that was no consolation to me as I was well aware of what I had done.  I called Lexmark to get replacements for the parts I had determined were bad, and as I stood there waiting for the tech to finish filling out forms (he was helpful, to be sure, but that sort of thing is never quick) I considered the mess I had made.

It was dry toner, after all, finely powdered plastic.  A vacuum cleaner had already failed to remove it from the carpet, so the particles must have been entangled with the carpet fibers.  Was there still a way to remove it dry?

Then I considered the can of compressed gas (“duster”) I had brought in with me to clean the printer inside.  I sat down on the floor, phone pinned against my shoulder, and with one hand hovering curled behind the darkest spot I pointed the nozzle at the nearest edge and fired away.

A few sprays later, the toner was all (all!) out of the carpet; most was distributed on my guarding hand, which I cleaned up with a tissue.  Elated (as you might imagine) I moved on to the larger, paler mess and did the same thing.  I think I may have used up almost the whole can, but it was worth it.

So for anyone with a similar mess, before you get it wet, you might want to try my procedure.  I make no guarantees, but I promise you it worked for me.