by Wojciech Sura

Configuring perforce for use with Visual Studio

My favorite (and actually quite popular) diff/merge tool is Perforce’s p4merge. I like its clean interface and advanced comparison algorithms, which perform quite well even when faced with complicated modifications.

Perforce-compare Perforce-merge

There is a way to integrate Perforce with Visual Studio, but this operation is a little bit complicated due to specific Perforce requirements for merged files. Let’s do that step by step.

First of all, create two batch files in Perforce directory:

p4diff.bat

@ECHO OFF
START /WAIT /D "C:\Program Files\Perforce\" p4merge.exe -nl ""%6"" -nr ""%7"" ""%1"" ""%2""

p4merge.bat

@ECHO OFF
COPY /Y NUL ""%4""
START /WAIT /D "C:\Program Files\Perforce\" p4merge.exe -nb ""%8"" -nl ""%6"" -nr ""%7"" -nm ""%9"" ""%3"" ""%1"" ""%2"" ""%4""

Then open Visual Studio’s configuration window and navigate to source control user tools:

p4conf

Now add two tools. First for comparing:

Extension: .*
Operation: Compare
Command: C:\Program Files\Perforce\p4diff.bat
Arguments: %1 %2 "0" "0" "0" %6 %7

And second for merging:

Extension: .*
Operation: Merge
Command: C:\Program Files\Perforce\p4merge.bat
Arguments: %1 %2 %3 %4 "0" %6 %7 %8 %9

The reason for additional batch files is that Perforce expects, that the result of merging already exists, but on the other hand Visual Studio expects the merge tool to create this file.

If you use Microsoft Git Provider, to configure Perforce as a diff tool, run git bash in your repository and execute:

$ git config --local difftool.perforce.cmd '"C:\Program Files\Perforce\p4merge.exe" "$LOCAL" "$REMOTE"'
$ git config --local diff.tool perforce
by Andrzej Kowal

MSSQL on Amazon RDS runs out of space!

Let’s take a simple case which I needed to solve today: our MSSQL Server database hosted in Amazon RDS used whole storage space which we assigned at the moment it was created. Ok, no problem, let’s increase it. Hmm, but there is no such option. So maybe take an RDS snapshot and restore to a larger instance? Nope. Ok, then let’s create a backup file, create new RDS instance with larger storage and restore backup file to that instance? Wrong again. This is just not supported!

The solution is the SQL Azure Migration Wizard. It has many features, but the one we need is the one that moves existing database between servers. The migration includes schema and data. It will support any MSSQL server including Azure, RDS and standalone installations. To solve my problem I first created new RDS instance with same settings and larger storage. Then I migrated DB from the old instance to the new one (with full schema and data) using this tool.

Let’s see the migration process in details:

  1. Download and unzip the application. If you don’t have SQL Server installed on the computer where you run this tool you will need to install Shared Management Objects (SMO) and Command Line Tools from this link: http://www.microsoft.com/en-us/download/details.aspx?id=29065 (this is for MSSQL 2012). You can find the necessary links after expanding “Install Instructions” section.
  2. In some cases you need to edit to SQLAzureMW.exe.config file and adjust the path to folder where the scripts are stored (by default it is c:\SQLAzureMW\BCPData). These scripts can get large, depending on your database size.
  3. Run the tool.
  4. Choose analyze / migrate -> database
  5. Connect to source database (it can be RDS too – in my case it was the RDS instance where we reached storage size limit). If you don’t have a source DB but a backup file – simply restore it to any MSSQL server which you have access to (outside RDS of course). Then connect to that database.
  6. Generate scripts. You might want to take a look at advanced options – there is quite a few of them.
  7. After script is generated connect to target database (if it does not exist, you can create it during the migration process) and execute the import.

 

That’s it. I was working on a 20GB database and it took 15 minutes to pull data and prepare the scripts and around 90 minutes to push the data to target DB. To speed things up I was running this tool on an AWS EC2 instance, which was launched in the same region as RDS instance. After import I even managed to rename the new RDS instance to the old name, so I could keep the old connection strings in all the config files.

And what about Amazon’s guidelines for importing database into RDS? If you take a close look, you will see that one of suggested scenarios involves bcp.exe (Bulk copy, which is part of SQL Command Line Tools). Actually SQLAzureMW uses bcp.exe under the hood to perform the migration. My verdict: go for SQLAzureMW. Its simplicity makes it the best choice for an RDS MSSQL DBA.

by Njål

4K/UHD Display Connectivity

Large (> 30″) UHD/4K displays are finally starting to become affordable. Some people that I know have purchased cheap 4K tv’s and used them as computer monitors (for developement etc.) It gives you enormous screenspace – and the DPI is comparable to todays monitors (around 100+) – which means you won’t have to scale up fonts etc. like you would on a 28″ UHD/4K monitor. (The font upscaling works is not a problem on OS X – but it can be more painful on some programs in Windows – although it got a lot better in 8.1.)

But there is a big drawbacks with these cheap displays (and especially using them as computer monitors):

They usually only have HDMI (1.3) connections – meaning that you’ll only get a refresh rate of 30Hz. This means that you’ll get lagging – like illustrated below:

Luckily – manufacturers such as Philips and Panasonic are starting to release large 4k tv’s with DisplayPort and/or HDMI 2.0. These standards enables 60Hz+ refresh rates – which eliminates the lagging. DisplayPort 1.3 is currently the best standard of the two.

So make sure your display has DP and/or HDMI 2.0. You will regret buying a UHD device with HDMI 1.3 sooner or later – whether you plan to watch sports or use the display as a computer monitor.

Here are a few options that will soon be in stores:

Panasonic TX­50AX802
Rear_panel
This is a 50 inch UHD TV with both DisplayPort and HDMI 2.0 input! Is nice.

 
Philips BDM4065UC/00
phil
This is a more affordable and smaller 40″ UHD monitor than the Panasonic model. Has DisplayPort. Great Success.

by Wojciech Sura

Number of rows in all tables in MSSQL Server

During reverse-engineering of a project, I had a suspicion, that some of database tables are not used at all. I wanted to get number of rows in each tables, but there were like 200 tables and I didn’t wanted to go through them one-by-one. Quick search in the Internet revealed this useful query:

SELECT 
    t.NAME AS TableName,
    i.name as indexName,
    p.[Rows],
    sum(a.total_pages) as TotalPages, 
    sum(a.used_pages) as UsedPages, 
    sum(a.data_pages) as DataPages,
    (sum(a.total_pages) * 8) / 1024 as TotalSpaceMB, 
    (sum(a.used_pages) * 8) / 1024 as UsedSpaceMB, 
    (sum(a.data_pages) * 8) / 1024 as DataSpaceMB
FROM 
    sys.tables t
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
WHERE 
    t.NAME NOT LIKE 'dt%' AND
    i.OBJECT_ID > 255 AND   
    i.index_id <= 1
GROUP BY 
    t.NAME, i.object_id, i.index_id, i.name, p.[Rows]
ORDER BY 
    object_name(i.object_id) 

Source: Stackoverflow.

by Wojciech Sura

Powershell philosophy

One way to think about Powershell is that it is a shell version of IEnumerable Linq extensions.

For instance, let’s imagine, that we want to know the size of the biggest .wav file in the folder. If we was in C#, the code would probably look like the following:

int size = Files.Where(f => f.Name.Contains(".wav")).OrderBy(file => file.Size).Last().Select(f => f.Size);

PowerShell version differs only by the syntax, philosophy is the same:

PS D:\Temporary> Get-ChildItem | Where-Object {$_.Name -like "*.wav"} | Sort-Object -Property Length | Select-Object -last 1 | Select-Object Length

They’re very similar, aren’t they?

by Njål

SSL v3.0 POODLE vulnerability – fixing on IIS

poodle_3

A few days ago 3 Google researchers discovered a nasty SSL security bug – named POODLE (“Padding Oracle On Downgraded Legacy Encryption”) – CVE 2014-3566.

This vulnerability affects servers still running SSL 3.0. It centers on cipher block chaining (CBC) encryption implementation and allow attackers with a Man-in-the-Middle (MITM) position to derive the contents of a secure payload based on responses received from requests sent from a compromised browser to a legitimate server.

The first thing you should do is check if this affects your site. Scan using SSL Toolbox – https://ssltools.thawte.com/checker/views/certCheck.jsp

If this issue is detected – then you should disable SSL 3.0 support or disable SSL 3.0 CBC-mode ciphers. Here’s a bat file which does the job – just run it as a an administrator on your IIS server – and reboot.

REG ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" /v Enabled /t REG_DWORD /d 0 /f
REG ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" /v Enabled /t REG_DWORD /d 0 /f
REG ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" /v Enabled /t REG_DWORD /d 0 /f
REG ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client" /v Enabled /t REG_DWORD /d 0 /f
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\DES 56/56" /v Enabled /t REG_DWORD /d 00000000 /f
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 40/128" /v Enabled /t REG_DWORD /d 00000000 /f
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 56/128" /v Enabled /t REG_DWORD /d 00000000 /f
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 128/128" /v Enabled /t REG_DWORD /d 00000000 /f
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 40/128" /v Enabled /t REG_DWORD /d 00000000 /f
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 56/128" /v Enabled /t REG_DWORD /d 00000000 /f
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 64/128" /v Enabled /t REG_DWORD /d 00000000 /f

 

Rescan using SSL Toolbox after the reboot to make sure the vulnerability have been removed from your server.

by Wojciech Sura

Scheduled recording internet streams

I’m a big fan of jazz. I can listen to this kind of music for hours.

One of the biggest Polish jazz composers and players, Jan “Ptaszyn” Wróblewski runs a radio show called “three-quarters of jazz” (its played in 3rd program of Polish Radio, hence the name). Unfortunately, it’s aired at 11pm, which is a little bit outside my range of consciousness.

But hey, I have a few GHz at my disposal. Let’s make use of them and ask the computer to record the show for me (fortunately, 3rd program of Polish Radio is streamed through the Internet as well).

My program of choice is VLC Player. This inconspicuous program offers more than you might think. It’s free and you can download it from its homepage.

Let’s now prepare a batch command, which will ask VLC to record the show. It looks like the following:

cd "C:\Program Files\VideoLAN\VLC"
"C:\Program Files\VideoLAN\VLC\vlc.exe" mms://stream.polskieradio.pl/program3 --run-time=4200 --sout "#transcode{acodec=mp3}:std{access=file,dst=D:\Dokumenty\Muzyka\Trojka.mp3}" vlc://quit

Let’s break it into parts.

  • mms://stream.polskieradio.pl/program3 – this is the URL to stream I want to record.
  • –run-time=4200 – time of recording in seconds. I record five preceeding and five following minutes (4200 = 1:10:00)
  • –sout - tells the VideoLan to stream the output. Following string informs about streaming details.
  • #transcode{acodec=mp3} – appends a filter on the output stream, which encodes it to MP3 format.
  • :std{access=file,dst=D:\Dokumenty\Muzyka\Trojka.mp3}” – appends a filter on the stream encoded to mp3, which simply saves it to a file.
  • vlc://quit – this is actually second item in the playlist. When you ask VLC player to play this file, it’ll simply close.

The rest is simply a matter of adding an entry to Windows Scheduler.

You can read more about configuring streaming in the command line in VLC documentation.

Bonus chatter: If you want the computer to shut down after recording the stream, add another (carefully timed) entry to Windows Scheduler and call:

shutdown /s /t 0
by Wojciech Sura

Snoop – a WPF window inspector

If you’re developing programs with Windows Presentation Foundation, there is a program, which, if you don’t already know, you surely should.

Snoop is a very interesting free utility, which allows inspecting WPF visual tree structure of an application during the runtime – and works completely standalone from the IDE. But that’s not all: you may inspect every single UI element along with its full list of properties and information, where the value comes from (direct, inherited, binding, resource etc.) and change them to observe, what happens.

And what if the visual of interest is buried deeply in the visual tree? That’s not a problem at all – after inspecting window with Snoop, simply hold Ctrl+Shift and hover mouse over that item – Snoop will find it for you.

snoop

Since a few versions of Visual Studio are written in WPF, you may Snoop them as well. That’s actually very useful, when you’re developing an extension editor for the IDE.

by Wojciech Sura

In operator in C#?

Most languages provides a very useful in operator, which tests, whether item is in specific collection, for instance, in Delphi:

if state in [State1, State2, State3] then Writeln("State 1-3!");

C# unfortunately lacks this operator, but we may cheat a little and reverse the condition:

if (new[] { MyStates.State1, MyStates.State2, MyStates.State3 }.Contains(state))
    Console.WriteLine("State 1-3!");

It is decision of developer, whether this notation is clear enough. The alternative is either test different conditions:

if (state == MyStates.State1 || state == MyStates.State2 || state == MyStates.State3)
    Console.WriteLine("State 1-3!");

Or you may store the required states in some temporary variable:

var states = new[] { MyStates.State1, MyStates.State2, MyStates.State3 };
if (states.Contains(state))
    Console.WriteLine("State 1-3!");

The first option seems the most elegant to me though.

by Wojciech Sura

How to create a pure WinAPI window?

Have you ever wondered, how does the mostly low-level Windows application look? I mean, one, which has at least one window. Well, here you go:

#include <Windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_DESTROY:
        {
            PostQuitMessage(0);

            return 0;
            break;
        }
    default:
        {
            return DefWindowProc(hwnd, message, wParam, lParam);
        }   
    }
}

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // Registering window class
    WNDCLASSEX winClass;
    winClass.cbClsExtra = 0;
    winClass.cbSize = sizeof(WNDCLASSEX);
    winClass.cbWndExtra = 0;
    winClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    winClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
    winClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
    winClass.hInstance = hInstance;
    winClass.lpfnWndProc = WindowProc;
    winClass.lpszClassName = L"MainWindowClass";
    winClass.lpszMenuName = NULL;
    winClass.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClassEx(&winClass))
        return -1;

    // Creating a window
    HWND mainWinHWND = CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
        L"MainWindowClass",
        L"WinAPI window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        640,
        480,
        NULL,
        NULL,
        hInstance,
        NULL);

    if (!mainWinHWND)
        return -1;

    ShowWindow(mainWinHWND, SW_SHOW);

    // Processing messages
    MSG message;
    BOOL getMsgResult;

    while ((getMsgResult = GetMessage(&message, NULL, 0, 0)) != 0 && getMsgResult != -1)
    {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }

    return message.lParam;
}

Now a few words of comments:

  1. Windows applications are driven by so-called messages: most of events are reported to an application in the form of a message. System maintains a message queue for each process and allows application to query for incoming messages. Message processing, however, has to be implemented by the programmer manually (the last while loop is usually called “main message loop”).
  2. A message is a simple structure consisting of the following fields:
    • A message code (int), for example mouse left button down is 0x201 = 513 (dec)
    • Two parameters: WParam and LParam (ints). If there’s a need to pass more data, LParam usually represents a pointer to bigger structure.
    • Target window handle (HWND, pointer)
  3. Applications receive a lot of messages, but fortunately Windows API provides a function, which processes them in a default way, if programmer didn’t planned anything special for them.
  4. Before window may be created, programmer has to define special window class, which describes window’s properties.
  5. Now an interesting fact. A “window” in terms of Windows API is not only awindow. Actually, every single UI object: button, checkbox, listbox etc., is a window and has its own window class. Windows API provides a set of default classes for most common controls you might want to use. I guess, that this is the real reason for the operating system to be named “Windows”

Before you urge to write a new application in pure WinAPI, here’s the equivalent of mentioned source code in C#/Windows Forms:

Form form = new Form();
form.Show();