0 Comments

Since I play a lot with IoT using my Raspberry Pi – on both – Windows and Raspbian, I ended up holding several SD cards, which don’t report almost any size on Windows. Somehow they are seen only as 70MB disks, even if they originally were 32GB cards. Where are then the missing bytes? Believe me, they are there and it’s simply the partition table (written on top of the SD card) that makes them hidden or treated even as unallocated space. And because Windows Explorer doesn’t allow any advanced management on that front, as its only feature - drive format - is not powerful enough, we need to go one level deeper.

Here is my recipe. If you browse the Internet, lots of people suggest using SD Association’s formatter tool. I confirm, it might be OK and it worked for me several times. But there is also another way, that uses build-in command-line utility called diskpart. This little tool will serve all our needs and we will feel like true admins. One *warning* before starting – it’s so powerful that I recommend double-checking all executed commands and their contexts to avoid accidental damages done to system disk and its partitions.

After that, all is more less straightforward. Run command-console in admin mode and execute (assuming the SD card is already somehow connected to the PC):

a) list available drives

b) select drive, where to restore full capacity

c) verify existing partitions

d) clear it

e) create a primary partition occupying whole available space

f) have fun!

 

Full listing from my sample session looks like following:

 

C:\WINDOWS\system32>diskpart

Microsoft DiskPart version 10.0.10240

Copyright (C) 1999-2013 Microsoft Corporation.
On computer: TAJFUN

DISKPART> list disk

  Disk ###  Status         Size     Free     Dyn  Gpt
  --------  -------------  -------  -------  ---  ---
  Disk 0    Online           29 GB      0 B        *
  Disk 1    Online           29 GB    22 GB

DISKPART> select disk 1

Disk 1 is now the selected disk.

DISKPART> list disk

  Disk ###  Status         Size     Free     Dyn  Gpt
  --------  -------------  -------  -------  ---  ---
  Disk 0    Online           29 GB      0 B        *
* Disk 1    Online           29 GB    22 GB

DISKPART> list part

  Partition ###  Type              Size     Offset
  -------------  ----------------  -------  -------
  Partition 1    Primary             64 MB  2048 KB
  Partition 0    Primary           4276 MB    72 MB
  Partition 0    Primary            600 MB  4348 MB
  Partition 0    Extended          2424 MB  4948 MB
  Partition 0    Logical           1024 KB  4948 MB
  Partition 0    Logical           2420 MB  4952 MB

DISKPART> clean

DiskPart succeeded in cleaning the disk.

DISKPART> create part pri

DiskPart succeeded in creating the specified partition.

DISKPART> list part

  Partition ###  Type              Size     Offset
  -------------  ----------------  -------  -------
* Partition 1    Primary             29 GB  1024 KB

Once done, this partition on SD card can be formatted as FAT32, NTFS or anything else.

0 Comments

I have a few command-line applications running on Windows. I haven’t written them myself, they are just ports of some Linux/Unix utilities. And there are situations, when I simply want them to stop or to pay more attention to me. Sure, I could make them to exit using TerminateProcess from my manager application, but this seems to be quite rude, even in the IT world. Much cleaner and nicer way would be to send them a polite notification, that would wake them up, allow release used resources (as some communicate with remote servers) and handle the exit themselves. Thankfully there is such a notification - console Ctrl-C signal (not the copying shortcut!).

As it turned out, it is a very popular subject on the Internet, where of course 99% of the solutions are very dirty hacks (like SendSignal or its improvements), that just work on some versions of Windows by accident etc. They tend to call some kernel-level handlers by using remote threads. OMG!

Another approach could be using GenerateConsoleCtrlEvent API. It does all what is needed, but the MSDN documentation doesn’t explain few caveats. To make it actually work, the process that calls the function must share the console with the one we want to send it, otherwise it won’t work. That also means the sender will receive that signal, too. By default on Windows it simply exits the process, if you have a GUI application, what might look like, it doesn’t work and crashed. Additionally on Windows all child processes inherit the parent’s console handle, if the parent is created with CREATE_NEW_PROCESS_GROUP flag. My first approach (which I borrowed from the BlackBerry Native Development plugin for Visual Studio) was to actually do it following way. I had a ‘wrapper’, that I was able to communicate with, which would trigger the Ctrl-C signal and could also spawn other child-processes, I wish to have a control over. That was OK, it helped in having some ‘domains’ of applications, although it required a lot of coding (especially the communication part and passing startup arguments for childs processes), but was working fine.

Recently, I found a simpler solution here, for scenarios, where there is no need for having groups of applications Ctrl-C should be delivered the same time. That’s correct – not the accepted answer. You can read author’s blogs post too and grab the source-code. The trick is, instead of writing another ‘wrapper’ application, it’s possible to issue the Ctrl-C directly from the manager application. We simply attach to the console of the desired program, disable exiting of the manager in case of Ctrl-C, call GenerateConsoleCtrlEvent and restore handling Ctrl-C.

Here is C# snippet from StackOverflow with few additions.

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AttachConsole(uint dwProcessId);

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool FreeConsole();

[DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate handler, bool add);

// Delegate type to be used as the Handler Routine for SCCH
delegate Boolean ConsoleCtrlDelegate(CtrlTypes type);

// Enumerated type for the control messages sent to the handler routine
enum CtrlTypes : uint
{
    CTRL_C_EVENT = 0,
    CTRL_BREAK_EVENT,
    CTRL_CLOSE_EVENT,
    CTRL_LOGOFF_EVENT = 5,
    CTRL_SHUTDOWN_EVENT
}

[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);

public static void StopProgram(uint pid)
{
    // It's impossible to be attached to 2 consoles at the same time,
    // so release the current one.
    FreeConsole();

    // This does not require the console window to be visible.
    if (AttachConsole(pid))
    {
        // Disable Ctrl-C handling for our program
        SetConsoleCtrlHandler(null, true);
        GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0);

        // Must wait here. If we don't and re-enable Ctrl-C
        // handling below too fast, we might terminate ourselves.
        Thread.Sleep(2000);

        FreeConsole();

        // Re-enable Ctrl-C handling or any subsequently started
        // programs will inherit the disabled state.
        SetConsoleCtrlHandler(null, false);
    }
}

This still could be improved by writing own more sophisticated handler (to avoid the sleep). More info here.

0 Comments

Let me test syntax highlighting on this new blog with the following simple snippet.

set CurrentDir=%~dp0
set CurrentDir=%CurrentDir:~0,-1%

It simply gets the full path (drive plus directory) without the trailing backslash, where the executed script is located. It useful in all situations, where you have have other resources next to the script and you don’t want to relay on current working directory to access them.